C# - 从客户端检查 TCP/IP 套接字状态

标签 c# tcp connection client-server polling

我想为我的 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/

相关文章:

c# - 以编程方式从 Entity Framework 6 的对象上下文中获取有关索引和约束的元数据

c# - 访问 Azure 表存储

C++ 限制 tcp 连接上的数据

mysql - 在 mysql 数据库中所做的更改不会反射(reflect)在 vb.net 应用程序中

ffmpeg - 要求ffmpeg等待rtp源的重新连接

hadoop - 数据基础架构实现-最佳方法

c# - 如何包装ffmpeg以在c#中转换视频

c# - 循环变量未被收集

string - Erlang:将 TCP 发送的字符串转换为正确的形式,例如<<"SomeString">> 到 "SomeString"?

networking - twisted .loseConnection 不会立即失去连接?