【问题标题】:When is a TCP connection considered idle?TCP 连接何时被认为是空闲的?
【发布时间】:2016-10-21 10:32:18
【问题描述】:

我需要在任何连接上启用 TCP keepalive,现在我正在努力处理我们测试用例的结果。我认为这是因为我不太了解何时发送第一个 keepalive 探测。我在 Linux 上 tcp_keepalive_time 的文档中阅读了以下内容:

最后一个数据包发送(简单的ACKs不被认为是数据)和第一个keepalive探测之间的间隔;之后 连接被标记为需要保持活动,此计数器未使用任何 进一步

其他一些消息来源指出这是连接空闲的时间,但他们没有进一步定义这意味着什么。我还研究了史蒂文斯以找到一个更正式的定义,因为我想知道在考虑重传时“发送的最后一个数据包”实际上意味着什么。

在我的测试用例中,我有一个连接,其中数据仅以相当高的速率从服务器发送到客户端。为了测试 keepalive,我们拔掉了客户端 NIC 上的电缆。我现在可以看到网络堆栈尝试发送数据并进入重传状态,但没有发送保持活动探测。重传时不发送keep alive探针是否正确?

【问题讨论】:

  • 如果您“以相当高的速率发送”,那么您的“启用 TCP keepalive”的要求一开始就没有意义。
  • @EJP 我们还有其他连接,例如不要发送任何数据,以及仅以低速率发送的其他数据。此外,这是客户直接对我们提出的要求。他们在全球范围内使用它。
  • 我假设您指的是在所有连接上设置 SO_KEEPALIVE(默认为“关闭”)?如果是这样,您只会在之后看到一个 keepalive 数据包(Linux 上的默认值为 2 小时),但拔出技巧应该可以工作(如果它没有发送其他数据)。
  • @rogerdpack 是的,我们必须在默认情况下启用所有连接上的保持活动作为客户的强制性要求。直到发送第一个保持活动数据包的时间还包括 TCP 重试时间。 cnicutar 的回答提供了详细信息。

标签: linux sockets tcp keep-alive retransmit-timeout


【解决方案1】:

我有一个连接,其中数据仅从服务器发送到客户端 以相当高的速度。

那么你将永远不会看到 keepalives。当“线路保持沉默”时,会发送 Keepalive。 RFC1122有一些解释re keepalives。

“保持活动”机制会定期探测网络的另一端 连接空闲时,即使有 没有要发送的数据

回到你的问题:

其他一些消息来源指出这是连接空闲的时间, 但他们没有进一步定义这意味着什么。

这是 TCP 在戳对端“天哪!还活着?”之前将等待多长时间。

$ cat /proc/sys/net/ipv4/tcp_keepalive_time
7200

换句话说,您一直在使用 TCP 连接,而且非常棒。但是,在过去的 2 个小时里,没有任何东西可以发送。假设连接仍然存在是否合理?假设中间的所有中间盒仍然具有您的连接状态是否合理?意见不一,keepalive 不是 RFC793 的一部分。

TCP 规范不包括它的保持活动机制 可能:(1)在瞬态期间导致完全良好的连接中断 互联网故障; (2) 消耗不必要的带宽(“如果没有人 使用连接,谁在乎它是否仍然良好?”)


为了测试 keepalive,我们拔掉了客户端 NIC 上的电缆。

这不是在测试 keepalive。这是测试您的 TCP 重传策略,即 TCP 尝试传递您的消息的次数和频率。在 Linux 机器上,这(可能)最终会测试 net.ipv4.tcp_retries2

在终止活动 TCP 连接之前要重试多少次。 RFC 1122 说限制应该超过100秒。它太小了 数字。默认值 15 对应于 13-30 分钟,具体取决于 RTO。

RFC5482 - TCP User Timeout Option 提供了更多影响它的方法。

TCP 用户超时控制传输的数据可以保留多长时间 在强制关闭连接之前未确认。

回到问题:

重传时不发送keep alive探针是否正确

这是有道理的:TCP 已经在尝试从其他对等点引出响应,空的 keepalive 将是多余的。


Linux 特定 (2.4+) options to influence keepalive

  • TCP_KEEPCNT TCP 在断开连接之前应发送的最大保活探测数。

  • TCP_KEEPIDLE 如果已在此套接字上设置了套接字选项 SO_KEEPALIVE,则在 TCP 开始发送 keepalive 探测之前连接需要保持空闲的时间(以秒为单位)

  • TCP_KEEPINTVL各个keepalive探测之间的时间(以秒为单位)

Linux 特定 (2.6.37+) option to influence TCP User Timeout

TCP_USER_TIMEOUT 中的最大时间量 传输数据之前可能保持未确认的毫秒数 TCP 将强制关闭连接。

因此,例如,您的应用程序可以使用此选项来确定在没有连接时连接可以存活多长时间(类似于您的 NIC 拔出示例)。例如。如果您有理由相信客户会回来(也许他们关上了笔记本电脑的盖子?无线访问不稳定?)您可以指定 12 小时的超时时间,当他们回来时,连接仍然有效。

【讨论】:

  • 仅供参考,Linux 2.4+ 具有TCP_KEEPIDLETCP_KEEPINTVLTCP_KEEPCNT 选项,用于设置探测开始前的空闲时间、探测之间的时间间隔以及最大探测次数分别发送探测。
  • @RemyLebeau 整洁。随时编辑答案以指出这一点!
  • @cnicutar 你有我可以参考的来源,它描述了在重传期间没有发送保持活动探测吗?似乎这因系统而异,例如在 Windows 上似乎有所不同。
  • @Jens 我没有消息来源。继续发送 keepalive 探测并不违法,但意义不大:如果 TCP 已经在发送内容,则对方已经有理由 ACK(这将证明连接是活动的)。
  • @cnicutar 很好的答案。还可以通过在 linux 上包含有关 TCP_USER_TIMEOUT 的信息来稍微改进它。似乎 OP 和其他人在搜索关于为什么保持活动仅适用于空闲或等待数据未到达的连接的答案时,会想知道如何设置每个连接的重新传输超时。
猜你喜欢
  • 2011-07-07
  • 2020-04-29
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-19
  • 2018-07-15
  • 1970-01-01
相关资源
最近更新 更多