c++ - 如何检测TCP连接中网线被拔掉?

标签 c++ sockets tcp network-programming

我有一个 C++ 网络应用程序,它接受来自客户端的 TCP 连接,然后在套接字上等待,直到客户端决定发送数据(有时它们很长时间都不会发送任何东西,这没关系)。

它主要检测客户端崩溃或机器关闭时的错误情况,但它需要很长时间才能注意到客户端的网络电缆何时被拔掉,我希望它尽快注意到这种情况。

我无法控制客户端,我无法让他们发送类似“ping”的信息。我的服务器确实向客户端发送了一个“ping”数据包(但他们不会发送响应),但即使拔下电缆 write() 也会返回正确的字节数(我看到 TCP 堆栈发送重试Wireshark 中的数据包)。

注意连接丢失的最佳方法是什么?如果我能在 write() 调用中检测到它,那将是最方便的。

我需要这个才能在 Windows 和 Linux 上工作。

最佳答案

不幸的是,无法区分电缆在另一端被拔出与任何其他丢包原因。话虽如此,您可以将另一端的连接丢失近似为在足够长的时间段(比如 T)内发生的“无限期数据包丢失”。 TCP 跟踪数据包丢失,因此执行此操作的一般方法是:

  • 获取连接中未确认的字节数(假设是 B)
  • 发送数据,size = N
  • 设置超时 = T,当它触发时,再次检查未确认的字节数。如果是 B+N,则假设另一端已失去连接。此时,您可以尝试 ICMP echo 来验证您的假设。

获取连接的 TCP 特定信息不是 UNIX 上的标准接口(interface),而且绝对不能移植到 Windows。在 Linux 上,有一个名为 TCP_INFO 的套接字选项,您可以通过 getsockopt() 调用它。谷歌应该给你一些例子。我不知道 Windows 上是否有等效选项。

另一种方法(即近似跟踪连接丢失)是通过 RAW 套接字。打开一个 RAW 套接字并过滤它以仅接收连接的 TCP 流量。然后,不是从 TCP 获取信息来确定您是否从另一端获得任何东西,而是简单地等待从另一端接收任何数据包。如果你在规定的时间内得到了一些东西,那么就说明对端还在。

关于c++ - 如何检测TCP连接中网线被拔掉?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14227007/

相关文章:

c++ - 对 C++ 的哪些更改使复制初始化适用于具有显式构造函数的类?

C++ wstringstream << NULL

C:套接字:无法读取整个服务器响应

java - java中如何停止或杀死一个线程?

c++ - 有没有更简单的方法来编写这部分代码?

c++ - Visual Studio & ffmpeg : Building FFmpeg in visual studio - 'ffmpeg.obj'

java - 与 Spring Integration 框架的 Tcp 连接

c# - 每个套接字地址(proto/ip/port)只能使用一次

linux - 在 Linux 中处理 c10k

sockets - 去吧,tcp打开文件太多调试