如何判断Socket何时断开连接

Bow*_*opa 16 .net c# sockets

在客户端,我需要知道何时/如果我的套接字连接已被破坏.但是,即使服务器端已断开连接并且我已尝试通过它发送数据,Socket.Connected属性也始终返回true.任何人都可以帮我弄清楚这里发生了什么.我需要知道套接字何时断开连接.

        Socket serverSocket = null;
        TcpListener listener = new TcpListener(1530);
        listener.Start();
        listener.BeginAcceptSocket(new AsyncCallback(delegate(IAsyncResult result)
        {
            Debug.WriteLine("ACCEPTING SOCKET CONNECTION");
            TcpListener currentListener = (TcpListener)result.AsyncState;
            serverSocket = currentListener.EndAcceptSocket(result);
        }), listener);


        Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        Debug.WriteLine("client socket connected: " + clientSocket.Connected);//should be FALSE, and it is
        clientSocket.Connect("localhost", 1530);
        Debug.WriteLine("client socket connected: " + clientSocket.Connected);//should be TRUE, and it is

        Thread.Sleep(1000);
        serverSocket.Close();//closing the server socket here
        Thread.Sleep(1000);

        clientSocket.Send(new byte[0]);//sending data should cause the socket to update its Connected property.
        Debug.WriteLine("client socket connected: " + clientSocket.Connected);//should be FALSE, but its always TRUE
Run Code Online (Sandbox Code Playgroud)

Dan*_*ach 10

在进行一些测试之后,似乎Socket.Connected的文档是错误的,或者至少是误导性的. clientSocket.Connected只会在clientSocket.close()被叫之后变为假.我认为这是原始C Berkeley套接字API及其术语的回归.当套接字具有与之关联的本地地址时绑定套接字,并且当套接字具有与之关联的远程地址时,将连接套接字.即使远程端已关闭连接,本地套接字仍然具有关联,因此它仍然"连接".

然而,这里是一个方法的工作:

!(socket.Poll(0, SelectMode.SelectRead) && socket.Available == 0)
Run Code Online (Sandbox Code Playgroud)

它依赖于这样一个事实:即使没有可用的数据,封闭连接也会被标记为可读.

如果要检测断开的网络电缆或计算机突然关闭等情况,情况会更复杂一些.在这些情况下,您的计算机永远不会收到指示套接字已关闭的数据包.它需要通过发送数据包并注意到没有响应返回来检测远程端已经消失.您可以在应用程序级别执行此操作作为协议的一部分,也可以使用TCP KeepAlive选项.使用.NET Keep Alive from .NET并不是特别容易; 你可能最好在你的协议中构建一个保持活动机制(或者,你可以问一个单独的问题"如何在.NET中启用TCP保持活动并设置保持活动间隔?").


Set*_* M. 0

clientSocket.Send() 方法是否等待数据包被 ack/nack'd?

如果不是,您的代码将飞到下一行,而套接字仍在尝试弄清楚发生了什么。