TcpClient.Close不会关闭连接

Bev*_*vin 2 c# networking tcpclient

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

现在,您询问这个问题是一个重复评论前一个,以及如何解决方案,可以发现在这里,相信我,当我说,我已经找到了这些,并试图他们.它没有帮助.我也尝试不同的组合TcpClient.Close,TcpClient.GetStream().Close()TcpClient.Dispose.什么都行不通.

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

有任何想法吗?

Chr*_*aas 8

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

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

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

  • 实际上,对于 TCP 连接来说,没有向服务器发送任何内容来告诉它它正在关闭的说法是不正确的。当 TCP 连接正常终止时,希望发起连接终止的一方发送一条带有 FIN 标志设置的消息。不幸的是,NetworkStream 或 TcpClient 类似乎没有任何方法来检测这种情况的发生,即使底层套接字 API 确实如此。所以,实际上,克里斯的回答是问题的正确解决方案。 (2认同)