2015-08-08 106 views
6

我正在使用Microsoft提供的Async示例编写我的第一个TCP服务器。用于简单聊天的C#TCP服务器

https://msdn.microsoft.com/en-us/library/fx6588te(v=vs.110).aspx

我把一切都从示例工作。我将它扩展为一个简单的聊天程序。但是我无法遵循这个程序的步骤(可能是因为它的异步性)。当收到消息时,它会回显客户端并关闭套接字。我没有看到它重新打开插座的位置。

public static void StartListening() { 
     // Data buffer for incoming data. 
     byte[] bytes = new Byte[1024]; 

     // Establish the local endpoint for the socket. 
     // The DNS name of the computer 
     // running the listener is "host.contoso.com". 
     IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); 
     IPAddress ipAddress = ipHostInfo.AddressList[0]; 
     IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); 

     // Create a TCP/IP socket. 
     Socket listener = new Socket(AddressFamily.InterNetwork, 
      SocketType.Stream, ProtocolType.Tcp); 

     // Bind the socket to the local endpoint and listen for incoming connections. 
     try { 
      listener.Bind(localEndPoint); 
      listener.Listen(100); 

      while (true) { 
       // Set the event to nonsignaled state. 
       allDone.Reset(); 

       // Start an asynchronous socket to listen for connections. 
       Console.WriteLine("Waiting for a connection..."); 
       listener.BeginAccept( 
        new AsyncCallback(AcceptCallback), 
        listener); 

       // Wait until a connection is made before continuing. 
       allDone.WaitOne(); 
      } 

     } catch (Exception e) { 
      Console.WriteLine(e.ToString()); 
     } 

     Console.WriteLine("\nPress ENTER to continue..."); 
     Console.Read(); 

    } 

private static void SendCallback(IAsyncResult ar) { 
     try { 
      // Retrieve the socket from the state object. 
      Socket handler = (Socket) ar.AsyncState; 

      // Complete sending the data to the remote device. 
      int bytesSent = handler.EndSend(ar); 
      Console.WriteLine("Sent {0} bytes to client.", bytesSent); 

      handler.Shutdown(SocketShutdown.Both); 
      handler.Close(); 

     } catch (Exception e) { 
      Console.WriteLine(e.ToString()); 
     } 
    } 

另外,将套接字打开是否正常?

+0

你知道如何写阻塞回声服务器?如果你这样做,那么你应该阅读关于反应堆和反应堆模式。 – John

+0

以下行:listener.Listen(100)。 – jdweng

+0

这是一个不好的MS样本。这里的异步IO并不是真正的异步,因为它等待完成。无意义。 – usr

回答

2

当收到消息时,它会回显客户端并关闭套接字。我没有看到它重新打开插座的位置。

那是因为它没有。通信完成后,服务器收到,发送回复,并完成该连接。它只是继续等待侦听套接字上的新连接。你有一段时间(真)。您将继续等待接受呼叫中的新传入连接。您将为每个新客户端获得一个新套接字。

此外,有不正常的平仓离场插座

是,监听套接字保持打开状态。这是保持开放,以继续使用接受

一种更好的方式使用异步写一个回声服务器接收新的连接,并伺机可以在这里找到:Using .Net 4.5 Async Feature for Socket Programming

+0

因此,套接字仍然打开,但与该客户端的连接已关闭?我认为我的实际问题应该是,“将客户端的连接断开”而不是套接字是正常的。 – user3822370

+1

你有这一切错误。侦听套接字处于侦听状态,并且从不用于实际连接。每当有传入连接时,会发生什么情况是侦听套接字被克隆到一个新套接字中,但是这是一个服务套接字,属于包含此服务套接字和连接套接字的套接字对。套接字对标识连接。监听套接字永远不会是套接字对的一部分,因此它不属于它所属的连接。它仅用作建立连接的一种方式。 –

+1

另请参阅我的答案在这里http://stackoverflow.com/questions/30054673/tcp-listener-and-client-listening-to-specfic-ip/30060384#30060384。如果这有助于您,请标记为有用或回答。 –