2010-09-23 39 views
2

我试图断开客户端与服务器的连接,但服务器仍然认为它正在连接。我无法找到解决方案,关机,断开和关闭所有不工作。断开TCPClient,并看到另一侧

来自客户端的我断开一些代码,检查服务器上:

客户:

private void btnDisconnect_Click(object sender, EventArgs e) 
    { 
     connTemp.Client.Shutdown(SocketShutdown.Both); 
     connTemp.Client.Disconnect(false); 
     connTemp.GetStream().Close(); 
     connTemp.Close(); 
    } 

服务器:

while (client != null && client.Connected) 
      { 
       NetworkStream stream = client.GetStream(); 
       data = null; 

       try 
       { 
        if (stream.DataAvailable) 
        { 
         data = ReadStringFromClient(client, stream); 
         WriteToConsole("Received Command: " + data); 
        } 
       } // So on and so on... 

还有更多的写入,并在进一步往下读码。

希望大家能帮忙。

更新:我甚至试图通过ref传递TCP客户端,假设有一个范围问题和客户端。即使读取后,连接保持为真。出了什么问题?

第二次更新!!:

下面是解决方案。做一个偷看并基于此,确定你是否连接。

if (client.Client.Poll(0, SelectMode.SelectRead)) 
        { 
         byte[] checkConn = new byte[1]; 
         if (client.Client.Receive(checkConn, SocketFlags.Peek) == 0) 
         { 
          throw new IOException(); 
         } 
        } 
+1

太可怕了,不是吗?客户端不会告诉服务器它已断开连接。如果服务器真的需要知道,它可以轮询套接字或尝试定期写入套接字。当然,客户需要了解并正确处理这些心跳。 – 2010-09-23 21:00:06

+0

轮询是不够的(“没有数据 - >没有问题”的原则)。你需要写一个套接字来确定它是关闭的。 – Bruno 2010-09-23 21:11:32

+0

哇。有没有更简单的解决方案? – 2010-09-23 21:27:46

回答

7

这里是解决方案!

if (client.Client.Poll(0, SelectMode.SelectRead)) 
       { 
        byte[] checkConn = new byte[1]; 
        if (client.Client.Receive(checkConn, SocketFlags.Peek) == 0) 
        { 
         throw new IOException(); 
        } 
       } 
+0

有关此解决方案的更多信息[此处](https://social.msdn.microsoft.com/Forums/zh-CN/c857cad5-2eb6-4b6c-b0b5-7f4ce320c5cd/c-how-to-determine-if-a-tcpclient都具有一个-被断开的?论坛= netfxnetcom) – StuartLC 2016-11-23 09:00:47

1

MSDN Documentation

connected属性获取客户机插座 的 连接状态作为最后一个I/O操作。

当它 返回false时,客户端套接字是 或者从未连接,或者是没有连接的 。由于 连接属性仅反映 连接状态 最近的操作,所以您应该尝试 发送或接收消息,以确定当前状态,即 。 消息发送失败后,此属性号 更长返回true。请注意,这个 行为是有意设计的。您不能 可靠地测试 连接的状态,因为在测试和发送/接收之间的时间 ,连接可能已经丢失。 您的代码应该假设连接的套接字是 ,并优雅地处理 失败的传输。

+0

这不工作。在while循环的底部,我做了另一个client.connected,它仍然返回true,即使我已经与服务器断开连接。现在怎么办? – 2010-09-23 21:10:54

0

这是一个通用的TCP问题,请参阅:

这种情况的解决方法往往依赖于数据的发送量预计为部分协议。这就是HTTP 1.1使用Content-Length标题(对于整个实体)或分块传输编码(具有各种块大小)。

另一种方法是定期发送“NOOP”或类似的命令(基本上不做任何事情但确保通信仍处于打开状态的消息)作为协议的一部分。

(您也可以添加到您的协议,客户端可以向服务器发送一个命令干净关闭连接,但没有得到它并不意味着客户端没有断开。)

1

我不确定NetworkStream类,但我认为它的行为类似于Socket类,因为它主要是一个包装类。一般情况下,服务器不会意识到客户端与套接字断开连接,除非它在套接字上执行I/O操作(读或写)。但是,当您在套接字上调用BeginRead时,在从套接字读取数据之前不会调用回调函数,因此调用EndRead并获取字节读取返回结果0(零)表示套接字已断开连接。如果您使用Read并获取零字节读取结果,我怀疑您可以检查底层Socket类上的Connected属性,如果客户端因为在套接字上执行了I/O操作而断开连接,则它将为false。

+0

这让我走上了正确的轨道......谢谢......参见上文。 – 2010-09-23 22:40:25

相关问题