如何关闭 TCP Keepalive?
Posted
技术标签:
【中文标题】如何关闭 TCP Keepalive?【英文标题】:How to turn TCP Keepalive off? 【发布时间】:2011-07-12 09:23:07 【问题描述】:我有一个充当服务器的 java 应用程序和一个充当客户端的 android 手机。它们通过 TCP 套接字进行通信。
我经常让客户端休眠,当它的缓冲区填满时,我希望 wifi 无线电能够进入休眠状态。问题是客户端没有睡觉。我注意到wireshark 说我的服务器大约每半秒发送一次TCP KeepAlive 数据包,因此wifi 无法休眠。我已经在服务器和客户端上尝试了以下操作。
connectionSocket.setKeepAlive(false);
但这似乎没有任何改变。我正在使用wireshark来分析流量。这是wireshark的屏幕截图......黑线表示我的客户在哪里睡觉并且它的接收缓冲区已满。我可以阻止服务器发送keepAlive数据包吗?
谢谢!
【问题讨论】:
我看不到你的屏幕截图。 "我注意到wireshark说我的服务器大约每半秒发送一个TCP KeepAlive数据包"这是什么平台?每半秒发送一次 TCP KeepAlive 探测似乎非常激进。 【参考方案1】:TCP 连接在关闭之前一直保持打开状态,这里的保持活动机制可以检测连接失败。
查看此链接:Does a TCP socket connection have a "keep alive"?
【讨论】:
啊,根据您链接中的一位同事的说法,我似乎无能为力。然后我的一个后续问题是,如果服务器发送了如此多的保持活动数据包,802.11psm 如何使无线电进入睡眠状态......似乎第一个是在 0.5 秒之后发送,然后是 1 秒,然后是 2 秒...... . soem 有点像指数函数,但它仍然需要几秒钟才能到达数据包相距足够远以睡眠的点。 我认为您有两个选择,要么关闭连接并在发送缓冲区内容之前重新打开它,要么使用 UDP(无连接)而不是 TCP。这是一个例子:java-samples.com/j2me/udp-datagram-free-j2me-sample-program.htm @JoelArnold,这个答案没有解释为什么函数 setKeepAlive(false) 不起作用.. @Pacerier 你是对的。再看一遍,我需要先看看 OP 的截图,然后才能说什么。数据包可能不是 TCP keepalive 数据包,因为默认延迟应至少为 2 小时...【参考方案2】:服务器和客户端之间的中间设备也会发起TCP keep-alive,如防火墙、网守。 看来客户端无法阻止 TCP keep-alive。
【讨论】:
TCP keep-alive 是可选的,需要默认关闭。 datatracker.ietf.org/doc/html/rfc1122#page-101 这个链接打不开,我使用的是基于okhttp的WebSocket,无法改变服务端环境,客户端能否停止服务端发送的TCP keep-alive包?感谢您的回复。 试试:rfc-editor.org/rfc/rfc1122.html#page-101 “服务端和客户端之间的中间设备也会发起TCP keep-alive”是哪些中间设备做的?? 比如GAP会是这样的。【参考方案3】:事实上,TCP 保持活动的行为取决于 TCP 堆栈的实现。话虽如此,应该遵循 RFC 标准。即使 TCP 实现支持 keep-alive,它也应该默认不使用它,除非在连接上请求。
见RFC 1122 section 4.2.3.6 "TCP Keep-Alives"
引用:
Implementors MAY include "keep-alives" in their TCP
implementations, although this practice is not universally
accepted. If keep-alives are included, the application MUST
be able to turn them on or off for each TCP connection, and
they MUST default to off.
【讨论】:
以上是关于如何关闭 TCP Keepalive?的主要内容,如果未能解决你的问题,请参考以下文章