TcpClient.Close不会关闭连接

时间:2011-02-02 20:11:08

标签: c# networking tcpclient

我有一个使用TcpClient和TcpListener通过网络进行通信的应用程序。但是,当我在客户端上调用TcpClient.Close以断开它与服务器的连接时,服务器根本不会做出反应。

现在,在您发布关于此问题的评论与this的问题重复之前,以及如何找到解决方案here之前,相信我,当我说我已经找到这些和尝试过他们。它没有帮助。我还尝试了TcpClient.CloseTcpClient.GetStream().Close()TcpClient.Dispose的不同组合。什么都行不通。

代码没有什么值得注意的,只是客户端中的Disconnect方法重置所有变量以便重用,并关闭所有网络资源。服务器有一个循环来检查TcpClient.Connected是否为真,如果它是假的,它应该跳出循环并终止该线程。

有什么想法吗?

2 个答案:

答案 0 :(得分:8)

TcpClient.Connected几乎应该被忽略。它基本上代表了最后一次沟通是否成功。来自MSDN(强调我的):

  

由于Connected属性仅反映最近操作时的连接状态,因此您应尝试发送或接收消息以确定当前状态。消息发送失败后,此属性不再返回true。请注意,此行为是设计使然。您无法可靠地测试连接状态,因为在测试和发送/接收之间的时间内,连接可能已丢失。 您的代码应该假设套接字已连接,并正常处理失败的传输。

如果你在客户端调用Close(),没有任何内容发送到服务器告诉它关闭它,它实际上只是自己关闭它,以便客户端不能再使用它。确定您是否仍然连接的唯一可靠方法是尝试发送数据并处理故障。如果你想要,你可以实现自己的握手协议,当你打电话给Close()时,你会向服务器发送一个特殊通知,提醒它事实,但仍然有时候该数据包永远不会到达服务器。

答案 1 :(得分:0)

听一个字节,如果已收到,请完成剩下的工作。 如果接收一个字节返回0,则客户端断开连接。

        IPAddress nReceiveAddress = IPAddress.Parse(GetIp(sSource));
        IPEndPoint localEndPoint = new IPEndPoint(nReceiveAddress, GetPort(sSource));
        Socket nSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        nSocket.Bind(localEndPoint);

        nSocket.Listen(10);
        Socket nSocketClient = nSocket.Accept();

                byte[] bufferOne = new byte[1];
                int nBytes = nClient.Receive(bufferOne);

                if (nBytes == 0)
                {
                    AppendToLog(String.Format("{0}: Closing.", sName));
                    nClient.Close();
                }
                else
                {
                    byte[] buffer = null;
                    buffer = new byte[nClient.Available + 1];

                    if (nClient.Available > 0)
                        nBytes = nClient.Receive(buffer);

                    if(nBytes>0)
                    {
                        //KS effectively insert the first received byte at start.
                        Array.Copy(buffer, 0, buffer, 1, buffer.Length - 1);
                        buffer[0] = bufferOne[0];
                    }
                }