C# TcpClient 不会注册断开连接

Posted

技术标签:

【中文标题】C# TcpClient 不会注册断开连接【英文标题】:C# TcpClient Won't Register Disconnect 【发布时间】:2017-01-18 21:22:55 【问题描述】:

我的服务器有一个“停止”按钮,应该断开客户端。我遇到的问题是客户端没有注册它已断开连接 - 或者它可能没有完全断开连接。当我点击服务器窗口上的红色“X”时,客户端将在控制台中写入它已断开连接,并尝试重新连接。那么,为什么我的停止按钮没有关闭窗口的效果呢?

希望这些 sn-ps 能让您更好地了解我遇到的问题:

这里是客户端。如您所见,它等待来自服务器的命令。如果“尝试”失败(服务器窗口已关闭),它知道它已断开连接,并说“客户端已断开连接”并尝试重新连接。

 public static void waitForCommands()
    
        while (client.Connected)
        
            try
            
                readBuffer = new byte[client.ReceiveBufferSize];
                int data = stream.Read(readBuffer, 0, readBuffer.Length);
                string plainText = Encoding.ASCII.GetString(readBuffer, 0, data);
                if (plainText.Contains("mbox"))
                
                    MessageBox.Show(plainText.Split('<','>')[1]);
                

                else if (plainText.Contains("process"))
                
                    Process.Start(plainText.Split('<', '>')[1]);
                
            

            catch
            
                MessageBox.Show("Client disconnected");
                new Thread(attemptConnection).Start();
            

        
    

这里是我的“停止”按钮的代码。它应该与关闭窗口具有相同的效果(减去应用程序关闭的部分),但事实并非如此。当我单击它时,它会导致客户端挂起。它甚至不会尝试重新连接。

private void simpleButton2_Click(object sender, EventArgs e)
    
        try
        
            f.labelControl1.Text = "Disconnected";
            client.Client.Disconnect(true);
            server.Stop();
        

        catch
        

        

    

除了“client.Client.Disconnect(true);”之外,我还尝试了许多其他代码行客户端.关闭(); ,client.Client.Close();,结果都一样

【问题讨论】:

它根本没有抛出任何错误 在关闭客户端之前先关闭流。让我们看看这是否有效,因为关闭客户端并不意味着流将关闭。 我切换了client.Client.Disconnect(true);与 client.GetStream().Close();和 client.Client.Close();似乎没有任何改变 请不要破坏您的帖子,您可以删除答案上的接受标记,然后单击问题下方的删除链接。 【参考方案1】:

当套接字断开连接时,另一端的stream.Read() 将返回 0 - 只有当服务器突然停止时,您的客户端才会在某些时候捕获异常。

所以只需添加一个检查 data == 0 来处理优雅的断开连接。关闭客户端的流以“完成循环”。

顺便说一句,您可能希望将catch (SocketException) 与其他异常区分开来,而不是假设“如果出现问题,服务器必须已停止”。

【讨论】:

我有一个小问题,如果你不介意回答(我在谷歌上找不到答案)client 和 client.Client 有什么区别? TcpClient.Client 属性获取用于与之通信的Socket。见msdn.microsoft.com/en-us/library/…

以上是关于C# TcpClient 不会注册断开连接的主要内容,如果未能解决你的问题,请参考以下文章

c# TCP/IP 自动断开

C# socket 如何断开连接

C#检查套接字是不是断开连接?

C#多线程聊天服务器,处理断开连接

Android ble 设备有时不会断开连接

socket.io 服务器在注册客户端断开连接时非常延迟