套接字断开通知方法

时间:2015-05-25 15:15:40

标签: c# multithreading sockets disconnect

刚刚搜索了一个posibble解决方案,以便在客户端断开连接时进行验证。 我发现了这个:

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

我在我的main中使用了一个while循环与thread.sleep(500)并运行Isconnectedmthod它在我通过visual studio运行它时工作正常,当我点击停止调试它实际上通知我在服务器端程序但是当我只是转到bin目录中的exe并启动它 - 它确实通知我连接但是当我关闭程序(手动从'x'按钮)或通过任务管理器时,IsConnected方法显然返回尚真..... 即时通讯使用简单的TCP连接

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

服务器:

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

            if (!IsConnected(s))


                MessageBox.Show("disconnected");
        }

(它在线程btw上运行)。

任何建议的家伙? 我甚至试图在客户关闭时关闭连接:

 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {

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

    }

不知道该怎么做

1 个答案:

答案 0 :(得分:2)

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

此规则存在一些与平台相关的异常,但没有涉及远程端点的简单消失。

客户端断开连接的正确方法是通过“关闭”操作正常关闭连接。在.NET中,这意味着客户端代码调用Socket.Shutdown(SocketShutdown.Send)。然后,客户端必须继续接收,直到服务器调用Socket.Shutdown(SocketShutdown.Both)。请注意,关闭“reason”通常是“发送”,用于启动关闭的端点,以及“两者”,用于端点确认并完成关闭。

每个端点将通过完成接收操作来检测另一个端点是否已关闭其结束,其中0作为该操作的字节计数返回值。在这个双向优雅闭包完成之前,任何一个端点都不应该关闭套接字(即调用Socket.Close())。即每个端点都调用Socket.Shutdown() ,看到零字节接收操作完成。

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

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

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