【问题标题】:C# TCP Server for simple chat用于简单聊天的 C# TCP 服务器
【发布时间】:2015-08-08 23:48:03
【问题描述】:

我正在使用 Microsoft 提供的 Async 示例编写我的第一个 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());
        }
    }

另外,让套接字保持打开状态是不正常的吗?

【问题讨论】:

  • 你知道怎么写阻塞回显服务器吗?如果你这样做了,那么你应该阅读反应器和前摄器模式。
  • 以下行:listener.Listen(100).
  • 这是不良 MS 样本之一。这里的异步 IO 并不是真正的异步,因为它等待完成。毫无意义。
  • @usr 这对他们有很大的误导......

标签: c# sockets tcp


【解决方案1】:

收到消息后,它会回显给客户端并关闭套接字。我看不到它会回到哪里重新打开套接字。

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

还有,让socket打开是不是很正常

是的,监听套接字保持打开状态。它保持打开状态以继续使用接受接收新连接

可以在此处找到使用 async 和 await 编写 echo 服务器的更好方法:Using .Net 4.5 Async Feature for Socket Programming

【讨论】:

  • 所以套接字仍然打开,但与该客户端的连接已关闭?我想我的实际问题应该是is it normal to leave the connection to the client open,而不是套接字。
  • 你错了。侦听套接字处于侦听状态,从未在实际连接中使用。每当有传入连接时,将发生的情况是侦听套接字被克隆到一个新套接字中,但这是一个服务套接字,属于包含此服务套接字和连接套接字的套接字对。套接字对标识连接。监听套接字绝不是套接字对的一部分,因此它不属于任何连接。它仅用作建立连接的一种方式。
  • stackoverflow.com/questions/30054673/… 也可以查看我的回答。如果对您有帮助,请标记为有用或回答。
  • 好的,您的链接帖子确实有很大帮助。所以我会再试一次!保持服务套接字打开是否正常? :)
  • 服务套接字在您的示例代码中关闭: handler.Shutdown(SocketShutdown.Both); handler.Close();具有明确请求回复机制的 Web 服务器将关闭连接。与 echoservers 相同,timeofday。但是聊天系统通常会让套接字打开更长的时间,这当然取决于它们的实现。
猜你喜欢
  • 2012-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-06
  • 2016-10-02
  • 1970-01-01
  • 2013-02-21
  • 2016-05-29
相关资源
最近更新 更多