TCP Socket 无连接超时

Posted

技术标签:

【中文标题】TCP Socket 无连接超时【英文标题】:TCP Socket no connection timeout 【发布时间】:2012-10-16 15:29:15 【问题描述】:

我打开一个 TCP 套接字并将其连接到网络上其他地方的另一个套接字。然后我可以成功发送和接收数据。我有一个计时器,它每秒向套接字发送一些东西。

然后我通过强行断开连接(在这种情况下拔出以太网电缆)粗鲁地中断连接。我的套接字仍在报告它每秒成功地写出数据。这持续了大约 1 小时 30 分钟,最终出现写入错误。

是什么指定了套接字最终接受另一端消失的超时?是操作系统(Ubuntu 11.04),是来自 TCP/IP 规范,还是套接字配置选项?

【问题讨论】:

或许this给你答案。 【参考方案1】:

拉网线不会中断 TCP 连接(1),但会中断通信。您可以重新插入电缆,一旦建立 IP 连接,所有的备份数据都会移动。这就是 TCP 可靠的原因,即使在蜂窝网络上也是如此。

当 TCP 发送数据时,它需要一个 ACK​​ 作为回复。如果在一段时间内没有出现,它会重新传输数据并再次等待。它在传输之间等待的时间通常呈指数增长。

在经过一定次数的重传或一段时间后没有 ACK 的情况下,TCP 将认为连接“断开”。多少次或多长时间取决于您的操作系统及其配置,但通常会超时几分钟。

来自 Linux 的tcp.7 man page:

   tcp_retries2 (integer; default: 15; since Linux 2.2)
          The maximum number of times a TCP packet is retransmitted in
          established state before giving up.  The default value is 15, which
          corresponds to a duration of approximately between 13 to 30 minutes,
          depending on the retransmission timeout.  The RFC 1122 specified
          minimum limit of 100 seconds is typically deemed too short.

这可能是您想要调整的值,以更改检测连接是否消失所需的时间。

(1) 有例外。操作系统在注意到电缆被移除后,可以通知上层所有连接都应被视为“断开”。

【讨论】:

我每天发出数千个 Http 请求,现在我在 Websockets(nodejs) 工作,所以我很自然地想了解更多关于好的旧套接字,我现在意识到 SocketsWork 是多么美丽。可靠的、面向连接的和主机特定的协议,因为这就是为什么不。重试次数取决于操作系统! 你能不能提一下recv/send-buffer大小的填充率?如果发送缓冲区已满,应用程序可能会收到 i/o 错误。 应用程序将不会收到 I/O 错误。一旦接收器的“接收窗口”为空,接收器将阻塞或读取零字节,具体取决于读取是同步的还是异步的。一旦他们的“发送窗口”(和任何其他操作系统缓冲区)已满,发送者将阻止或发送零字节,这也取决于。直到 TCP 确定连接“断开”后才会发生 I/O 错误。【参考方案2】:

如果想要将套接字错误快速传播到您的应用程序代码,您可能想尝试这个套接字选项:

TCP_USER_TIMEOUT(自 Linux 2.6.37 起) 此选项将 unsigned int 作为参数。当。。。的时候 值大于 0,它指定的最大数量 传输数据可能保留的时间(毫秒) 在 TCP 将强制关闭之前未确认 对应的连接并返回 ETIMEDOUT 到 应用。如果选项值指定为 0,TCP 将 使用系统默认值。

查看linux/man/tcp(7) 的完整描述。此选项比 tcp_retries2 编辑更灵活(您可以在创建套接字后立即设置它),并且完全适用于客户端的套接字不知道服务器的一个状态并且可能会进入所谓的半关闭状态。

【讨论】:

以上是关于TCP Socket 无连接超时的主要内容,如果未能解决你的问题,请参考以下文章

如何设置socket的Connect超时

Linux 建立 TCP 连接的超时时间分析

如何设置TCP sokcet连接的超时时间

linux下有系统tcp连接超时时间么

tcp连接状态有大量的timewait 状态,导致连接等待至超时,怎么解决

Tcp超时修改