我有一个连接,其中数据仅以相当高的速率从服务器发送到客户端。
然后你永远不会看到keepalives。当“线路保持沉默”时,会发送 Keepalive。RFC1122对keepalives 有一些解释。
当连接处于空闲状态时, “保持活动”机制会定期探测连接的另一端,即使没有要发送的数据也是如此
回到你的问题:
其他一些消息来源指出这是连接空闲的时间,但他们没有进一步定义这意味着什么。
这是 TCP 在戳对等方“天哪!还活着?”之前将等待多长时间。
$ cat /proc/sys/net/ipv4/tcp_keepalive_time
7200
换句话说,您一直在使用 TCP 连接,而且非常棒。但是,在过去的 2 个小时里,没有任何东西可以发送。假设连接仍然存在是否合理?假设中间的所有中间盒仍然具有您的连接状态是否合理?意见各不相同,keepalive 不是 RFC793 的一部分。
TCP 规范不包含保持活动的机制,它可能:(1)在短暂的 Internet 故障期间导致完全良好的连接中断;(2)消耗不必要的带宽(“如果没有人在使用连接,谁在乎它是否仍然好?”)
为了测试 keepalive,我们拔掉了客户端 NIC 上的电缆。
这不是测试保活。这是测试您的 TCP 重传策略,即 TCP 尝试传递您的消息的次数和频率。在 Linux 机器上,这(可能)最终会测试net.ipv4.tcp_retries2
:
在杀死活动 TCP 连接之前重试多少次。RFC 1122 说限制应该超过 100 秒。这个数字太小了。默认值 15 对应于 13-30 分钟,具体取决于 RTO。
但是RFC5482 - TCP User Timeout Option提供了更多影响它的方法。
TCP 用户超时控制在强制关闭连接之前传输的数据可能保持未确认的时间。
回到问题:
在重传期间不发送保持活动探针是否正确
这是有道理的:TCP 已经在尝试从其他对等方获取响应,空的 keepalive 将是多余的。
TCP_KEEPCNT
TCP 在断开连接之前应发送的最大保活探测数。
TCP_KEEPIDLE
SO_KEEPALIVE
如果已在此套接字上设置了套接字选项,则在 TCP 开始发送 keepalive 探测之前连接需要保持空闲的时间(以秒为单位)
TCP_KEEPINTVL
各个保活探测之间的时间(以秒为单位)
TCP_USER_TIMEOUT
在 TCP 强制关闭连接之前,传输数据可能保持未确认的最长时间(以毫秒为单位)。
因此,例如,您的应用程序可以使用此选项来确定在没有连接时连接可以存活多长时间(类似于您的 NIC 拔出示例)。例如,如果您有理由相信客户端会回来(也许他们关上了笔记本电脑的盖子?无线访问不稳定?)您可以指定 12 小时的超时时间,当他们回来时,连接仍然有效。