套接字断开通知方法

socket disconnection notification method

刚刚搜索了一个可能的解决方案来确定客户端断开连接的时间。 我发现了这个:

        public bool IsConnected( Socket s)
    {
        try
        {
            return !(s.Poll(1, SelectMode.SelectRead) &&s.Available == 0);
        }
        catch (SocketException) { return false; }
    }

我在我的主程序中使用 while 循环 thread.sleep(500) 和 运行 连接 Isconnectedmthod 当我 运行 它通过 visual studio 和当我单击停止调试时,它实际上会在服务器端程序中通知我,但是当我只是转到 bin 目录中的 exe 并启动它时 - 它确实会通知我连接但是当我关闭程序时(手动从 'x' 按钮)或通过任务管理器 IsConnected 方法显然 return 仍然正确..... 我正在使用简单的 TCP 连接

        client = new TcpClient();
         client.Connect("10.0.0.2", 10);

服务器:

Socket s = tcpClient.Client;
        while(true)
        {

            if (!IsConnected(s))


                MessageBox.Show("disconnected");
        }

(顺便说一句,运行正在线程上)。

大家有什么建议吗? 我什至尝试在客户端关闭时关闭连接:

 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {

        client.Close();
        s.Close();
        Environment.Exit(0);

    }

不知道该怎么办

您所要求的是不可能的。除非在连接上尝试 send,否则 TCP 不会报告连接错误。如果您的程序所做的只是接收,它永远不会注意到连接不再存在。

此规则有一些与平台相关的例外情况,但 none 涉及远程端点的简单消失。

客户端断开连接的正确方法是通过 "shutdown" 操作优雅地关闭连接。在 .NET 中,这意味着客户端代码调用 Socket.Shutdown(SocketShutdown.Send)。然后客户端必须继续接收,直到服务器调用 Socket.Shutdown(SocketShutdown.Both)。注意关闭"reason"对于端点发起关闭一般是"send",对于端点确认和完成关闭一般是"both"

每个端点将检测到另一个端点已通过接收操作的完成关闭其末端,其中 0 作为该操作的字节计数 return 值。两个端点实际上都不应该 关闭 套接字(即调用 Socket.Close()),直到这个双向优雅关闭完成。 IE。每个端点都调用了 Socket.Shutdown() 看到零字节接收操作完成。

以上是优雅闭包的工作原理,应该是server/client交互的规范。当然,事情确实会破裂。客户端可能会崩溃,网络可能会断开连接等。通常,正确的做法是尽可能延迟对此类问题的识别;例如,只要服务器和客户端不需要实际通信,那么暂时的网络中断应该不会导致错误。在那种情况下强迫一个是没有意义的。

换句话说,不要添加代码来尝试检测连接失败。为了获得最大的可靠性,让网络尝试自行恢复。

在一些不太常见的情况下,希望尽早检测到连接失败。在这些情况下,您可以在套接字上启用 "keep alive"(以强制通过连接发送数据,从而检测连接中的中断......请参阅 SocketOptionName.KeepAlive)或实施一些超时机制(以强制连接如果一段时间后没有数据发送则失败)。我通常建议不要使用这种技术,但在某些情况下这是一种有效的方法。