c # socket che gestiscono più client

Ho il seguente codice che voglio implementare come mio server. A quanto ho capito, è asincrono. e dovrebbe consentire le connessioni da più client …

public void Start() { TcpListener listener = new TcpListener(IPAddress.Any, 10250); listener.Start(); Console.WriteLine("Listening..."); while (true) { IAsyncResult res = listener.BeginAcceptTcpClient(HandleAsyncConnection, listener); connectionWaitHandle.WaitOne(); } } private void HandleAsyncConnection(IAsyncResult res) { TcpListener listener = (TcpListener)res.AsyncState; TcpClient client = listener.EndAcceptTcpClient(res); connectionWaitHandle.Set(); StringBuilder sb = new StringBuilder(); var data = new byte[client.ReceiveBufferSize]; using (NetworkStream ns = client.GetStream()) { // Test reply Byte[] replyData = System.Text.Encoding.ASCII.GetBytes(DateTime.Now.ToString()); ns.Write(replyData, 0, replyData.Length); ns.Flush(); ns.Close(); } client.Close(); } 

Ho una app di prova che semplicemente spara le richieste al mio server. Come puoi vedere nel codice, il server risponde semplicemente con la sua data / ora. L’app di test invia 20 richieste che sono semplicemente stringhe di test. Per ognuna di queste richieste apre un socket, invia i dati al mio server e quindi chiude di nuovo il socket.

Funziona perfettamente con un’applicazione di test in esecuzione. Tuttavia, se apro due app di test, la seconda non può connettersi al server. Ho pensato perché sto gestendo la richiesta asincrona. e poiché la mia app di test si apre, chiude il socket prima di ogni chiamata potrei gestire le richieste di più client?

modificare

Se si utilizza> =. Net4.5, è meglio utilizzare i nuovi metodi di rete che consentono l’adozione di async e await . Come tale, potrebbe essere meglio seguire l’esempio che ho fornito in questo post come punto di partenza.

Post originale

Nel codice seguente viene illustrato come accettare più client in modo asincrono senza creare una nuova discussione per connessione.

 private TcpListener listener; public void Start() { listener = new TcpListener(IPAddress.Any, 10250); listener.Start(); Console.WriteLine("Listening..."); StartAccept(); } private void StartAccept() { listener.BeginAcceptTcpClient(HandleAsyncConnection, listener); } private void HandleAsyncConnection(IAsyncResult res) { StartAccept(); //listen for new connections again TcpClient client = listener.EndAcceptTcpClient(res); //proceed } 

È ansible utilizzare questo modello per la maggior parte delle operazioni asincrone.

Il modo in cui l’hai fatto, non ha alcun vantaggio rispetto all’utilizzo di AcceptTcpClient . Semplicemente loop e creare un nuovo thread per ogni connessione accettata:

 public void Start() { TcpListener listener = new TcpListener(IPAddress.Any, 10250); listener.Start(); Console.WriteLine("Listening..."); while (canRun) { var client = listener.AcceptTcpClient(); new Thread(ClientThread).Start(client); } } private void ClientThread(IAsyncResult res) { TcpClient client = (TcpClient)res.AsyncState; StringBuilder sb = new StringBuilder(); var data = new byte[client.ReceiveBufferSize]; using (NetworkStream ns = client.GetStream()) { // Test reply Byte[] replyData = System.Text.Encoding.ASCII.GetBytes(DateTime.Now.ToString()); ns.Write(replyData, 0, replyData.Length); ns.Flush(); ns.Close(); } client.Close(); } 

Una regola d’oro quando si usano metodi asincroni è NON bloccare l’operazione. Il blocco vanificherebbe lo scopo dell’uso di operazioni asincrone.

 public void Start() { TcpListener listener = new TcpListener(IPAddress.Any, 10250); listener.Start(); Console.WriteLine("Listening..."); listener.BeginAcceptTcpClient(OnAccept, listener); } private void OnAccept(IAsyncResult res) { TcpListener listener = (TcpListener)res.AsyncState; TcpClient client = listener.EndAcceptTcpClient(res); StringBuilder sb = new StringBuilder(); var data = new byte[client.ReceiveBufferSize]; using (NetworkStream ns = client.GetStream()) { // Test reply Byte[] replyData = System.Text.Encoding.ASCII.GetBytes(DateTime.Now.ToString()); ns.Write(replyData, 0, replyData.Length); ns.Flush(); ns.Close(); } client.Close(); }