如何检测 TCP 连接中的网线已被拔掉?

Howto detect that a network cable has been unplugged in a TCP connection?(如何检测 TCP 连接中的网线已被拔掉?)

本文介绍了如何检测 TCP 连接中的网线已被拔掉?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a C++ networking application that accepts TCP connections from clients and then waits on the socket until the client decides to send data (sometimes they won't send anything for a long time and thats OK).

当客户端崩溃或机器关闭时,它主要检测错误情况,但是当连接到客户端的网络电缆被拔出时,它需要几分钟才能注意到,我希望它尽快注意到这种情况.

It mostly detects error conditions when clients crash or machines are turned off, but it takes many minutes to notice when the network cable to the client has been unplugged and I would prefer it to notice this condition as soon as possible.

我无法控制客户端,也无法让他们发送诸如ping"之类的内容.我的服务器确实向客户端发送了一个ping"数据包(但他们不会发送响应),但即使拔掉电缆 write() 也会返回正确的字节数(我看到 TCP 堆栈发送重试Wireshark 中的数据包).

I don't have control over the clients and I can't make them send something like a "ping". My server does send out a "ping" packet to the to the clients (but they won't send a response), but even when the cable is unplugged write() returns the correct number of bytes (I see the TCP stack sending retry packets in Wireshark).

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

What is the best way to notice the loss of connection ? It would be most convenient if I could detect it on the write() call.

我需要它在 Windows 和 Linux 上运行.

I need this to work on Windows and on Linux.

推荐答案

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

Unfortunately, there is no way to distinguish the cable being pulled out at the other end from any other reason for packet loss. Having said that, you can approximate loss of connectivity at the other end as "indefinite packet loss" occurring over a sufficiently long period of time (say T). TCP tracks packet loss, so the general approach for doing this would be:

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

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

Getting TCP-specific information for a connection is not a standard interface on UNIX, and definitely not something portable to Windows. On Linux, there's a socket option called TCP_INFO, which you can call via getsockopt(). Google should give you some examples. I don't know if there's an equivalent option on Windows.

另一种方法(即近似跟踪连接丢失)是通过 RAW 套接字.打开 RAW 套接字并对其进行过滤以仅接收连接的 TCP 流量.然后,与其从 TCP 获取信息以确定您是否从另一端获取任何信息,只需等待从另一端接收任何 数据包即可.如果你在规定的时间内得到了一些东西,那么这意味着peer仍然是up的.

Another way to do this (i.e. approximate tracking of connectivity loss) is via RAW sockets. Open a RAW socket and filter it to receive only TCP traffic for your connection. Then rather than fetching information from TCP to determine if you are getting anything from the other end, simply wait to receive any packet from the other side. If you get something in the stipulated period, then it means the peer is still up.

这篇关于如何检测 TCP 连接中的网线已被拔掉?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:如何检测 TCP 连接中的网线已被拔掉?

基础教程推荐