我想为我的 TCP/IP 客户端类提供 CheckConnection 函数,以便我可以检查是否发生了错误(我自己的客户端断开连接、服务器断开连接、服务器卡住等)。
我有类似的东西:
bool isConnectionActive = false;
if (Client.Poll(100000, SelectMode.SelectWrite) == true)
isConnectionActive = true;
根据 MSDN 的说法:
SelectWrite: true, if processing a Connect(EndPoint), and the connection has succeeded; -or- true if data can be sent; otherwise, returns false.
要点是,使用简单的服务器应用程序对此进行测试,即使服务器监听器已关闭并且服务器应用程序已关闭,我从 CheckConnection 中得到的结果始终为 true;这很奇怪,因为我预计在这些情况下,不会处理任何连接(几分钟前已连接)并且无法发送数据。
我已经使用 Poll 与 SelectRead 和 Available 的组合在服务器端实现了类似的连接检查,并且它似乎工作正常;那么现在,我应该在客户端写类似的东西吗? SelectWrite 方法是否正确(但我使用不当)?
最佳答案
您可以检查很多东西,但没有一个可以保证为您提供所需的结果。即使您在服务器上的实现也不会 100% 正常工作。我保证有一天它会失败。
存在 FIN 数据包,这些数据包应该从客户端发送到服务器,反之亦然,当连接关闭时,但不能保证这些数据包会被传递,甚至被处理。
这通常被称为 TCP Half Open问题。
关闭 TCP 套接字是一个双方同意的过程,您通常有一个消息协议(protocol)告诉另一端它正在关闭,或者您有一些预定义的指令集,然后关闭。
100% 检测远程套接字是否关闭的唯一可靠方法是向其发送一些数据。只有当您返回错误时,您才会知道套接字是否已关闭。
一些不发送大量数据的应用程序实现保持事件协议(protocol),它们只是每分钟发送/接收几个字节,因此它们知道远程端点存在。
从技术上讲,您可以拥有两台处于连接状态并且 10 年内没有相互发送数据的服务器。每一端都继续相信另一端在那里,直到尝试发送一些数据并发现另一端不存在。
关于C# - 从客户端检查 TCP/IP 套接字状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59964679/