如何判断 Socket 何时已断开连接

2024-02-08

在客户端,我需要知道我的套接字连接何时/是否已断开。但是 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

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

然而,这里有一个方法does work:

!(socket.Poll(0, SelectMode.SelectRead) && socket.Available == 0)

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何判断 Socket 何时已断开连接 的相关文章

随机推荐