2014-11-15 3 views
0

Я пытаюсь написать небольшую программу, созданную с сервера и некоторых клиентов. Сервер будет передавать/нажимать текстовое сообщение клиентам (клиенту не разрешено отправлять обратно на сервер, все клиенты должны получать то же текстовое сообщение с сервера) Я видел некоторый вопрос по этому вопросу вокруг здесь и за сетью, но не получил точного решения, которое я ищу. Большинство решений заключалось в создании потока для каждого клиента. но допустим, что я не всегда знаю, сколько клиентов будут слушать в определенное время. может быть 2 и может быть 30. Я знаю, что есть способ создания пула потоков, и пусть .NET имеет дело с назначением потоков, но никогда не имел хорошей практики с этим, и мои знания с Threading не являются хорошими. На данный момент у меня есть простая программа «Север-клиент», которая работает так, как ожидалось, но снова, только с одним клиентом. так вот мой код:C# TCP-сервер для нескольких клиентов (неизвестное количество клиентов, прослушивающих)

Сервер:

using System.Net; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 
using System.Windows; 

namespace NetMessageServerWpf 
{ 
    public partial class MainWindow : Window 
    { 
     TcpClient client; 

     public MainWindow() 
     { 
      InitializeComponent(); 
      this.tcpListener = new TcpListener(IPAddress.Any, 3000); 
      this.listenThread = new Thread(new ThreadStart(ListenForClients)); 
      this.listenThread.Start(); 
     } 

     private void btnSend_Click(object sender, RoutedEventArgs e) 
     { 
      if(client == null || !client.Connected) 
       client = this.tcpListener.AcceptTcpClient(); 
      msg = txtMessage.Text; 
      SendTCP(client); 
     } 

     public TcpListener tcpListener; 
     public Thread listenThread; 

     private string msg; 

     private void ListenForClients() 
     { 
      this.tcpListener.Start(); 
     } 

     public void SendTCP(TcpClient tcpClient) 
     { 
      NetworkStream clientStream = tcpClient.GetStream(); 
      ASCIIEncoding encoder = new ASCIIEncoding(); 
      byte[] buffer = encoder.GetBytes(this.msg); 
      clientStream.Write(buffer, 0, buffer.Length); 
      clientStream.Flush(); 
     } 
    } 
} 

Клиент:

using System.Net; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 

namespace NetClientSideWpf 
{ 
    class Client : Base 
    { 

     private string messageString; 
     public string MessageString 
     { 
      get { return messageString; } 
      set 
      { 
       messageString = value; 
       OnPropertyChanged("MessageString"); 
      } 
     } 


     public Client() 
     { 
      ConnectToServer(); 
     } 

     public void ConnectToServer() 
     { 
      TcpClient client = new TcpClient(); 

      IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000); 

      client.Connect(serverEndPoint); 


      NetworkStream clientStream = client.GetStream(); 

      Thread ServerThread = new Thread(new ParameterizedThreadStart(HandleClientComm)); 
      ServerThread.Start(client); 


     } 

     private void HandleClientComm(object client) 
     { 
      TcpClient tcpClient = (TcpClient)client; 
      NetworkStream clientStream = tcpClient.GetStream(); 

      byte[] message = new byte[4096]; 
      int bytesRead; 

      while (true) 
      { 
       bytesRead = 0; 

       try 
       { 
        bytesRead = clientStream.Read(message, 0, 4096); 
       } 
       catch 
       { 
        break; 
       } 

       if (bytesRead == 0) 
       { 
        break; 
       } 

       ASCIIEncoding encoder = new ASCIIEncoding(); 
       MessageString = encoder.GetString(message, 0, bytesRead); 
      } 
     } 
    } 
} 

любая помощь будет делать! :)

ответ

1

Я думаю, что сначала вы должны начать прослушиватель в начале вашего приложения. Затем посмотрите интервалы времени (Таймер) для входящих соединений (TCPListener.Pending http://msdn.microsoft.com/de-de/library/system.net.sockets.tcplistener.pending(v=vs.110).aspx) Если вы получаете соединение, вы должны сохранить TCPClient в списке. On Button Нажмите Отправить сообщения своим клиентам.

Я думаю, что это не самое лучшее решение, но это один без несколько нитей ;-)

Я написал некоторые примеры кода, надеюсь, что это поможет вам (не тестировались):

public partial class MainWindow : Window 
{ 

    private TcpListener _server; 
    private List<TcpClient> _connectedClients; 

    public MainWindow() 
    { 
     InitializeComponent(); 

     _server = new TcpListener(IPAddress.Any, 3000); 
     _connectedClients = new List<TcpClient>(); 
     _server.Start(); 

     DispatcherTimer timer = new DispatcherTimer(); 
     timer.Interval = TimeSpan.FromSeconds(1); //every 1 sec! 
     timer.Tick += timer_Tick; 
     timer.Start(); 
    } 

    private void SendMessage(string message) 
    { 
     ASCIIEncoding encoder = new ASCIIEncoding(); 
     byte[] buffer = encoder.GetBytes(message); 
     foreach (var client in _connectedClients) 
     { 
      NetworkStream clientStream = client.GetStream(); 
      clientStream.Write(buffer, 0, buffer.Length); 
      clientStream.Flush(); 
     } 
    } 


    void timer_Tick(object sender, EventArgs e) 
    { 
     Debug.WriteLine("Tick"); 
     Title = "hello"; 

     if (_server.Pending()) 
     { 
      _connectedClients.Add(_server.AcceptTcpClient()); 
     } 
    } 

} 
+0

Я отредактировав мой вопрос, я забыл упомянуть, что все клиенты должны получать одно и то же текстовое сообщение (поэтому я думаю, что нет необходимости «перечислять» их). Я не против использования потоков, но как я могу быть уверен, что у меня их достаточно и т. Д. –

+0

вы ДОЛЖНЫ их перечислить. У вас есть TcpClient для каждого подключенного клиента. Поэтому вы должны запомнить все, что есть в списке. Я не знаю свойства или метода на TCPListener для отправки сообщения всем клиентам. –

+0

Помогите мне привести пример с помощью моего кода? заранее спасибо –

Смежные вопросы