如何在Java或Netty中设置套接字选项(TCP_KEEPCNT,TCP_KEEPIDLE,TCP_KEEPINTVL)?

8

在C/Linux中,可以为每个TCP连接的保持活动选项单独设置不同的值。

TCP_KEEPCNT (自Linux 2.4起) 在放弃连接之前TCP发送的最大保持活动探测数。此选项不应在旨在可移植的代码中使用。

TCP_KEEPIDLE (自Linux 2.4起) 如果已在此套接字上设置了SO_KEEPALIVE套接字选项,则在连接保持空闲状态的时间(以秒为单位)之前,TCP开始发送保持活动探测。此选项不应在旨在可移植的代码中使用。

TCP_KEEPINTVL (自Linux 2.4起) 个别保持活动探测之间的时间(以秒为单位)。此选项不应在旨在可移植的代码中使用。

在netty或java中,如何为套接字设置这三个套接字选项?我知道没有可移植的方法来解决它,但只有在Linux中,才能设置这些套接字选项吗?


1
如您在文档中所述,这些选项“[...]不应用于旨在具有可移植性的代码”。如果您想使用这些选项,您需要使用JNI(或更好的JNA)并实现自己的“Socket”/“SocketFactory”。 - fge
请参考以下链接:https://dev59.com/UVfUa4cB1Zd3GeqPKKyJ,其中涉及Java程序中的setsockopt函数。 - Rahul R Dhobi
谢谢大家。需要使用JNA来实现它。 - Yang Juven
对于C ++,可以在此帖子中找到描述:Socket keepalive not working - iammilind
3个回答

4
看起来Java 11支持此功能,通过ExtendedSocketOptions类中的新字段。这些可以传递给java.net.Socketjava.nio.channels.SocketChannel上的setOption方法。
请注意,我实际上没有尝试使用它。文档明确指出这些是特定于平台的,因此您需要测试它们在您关心的平台上是否真正做到了您想要的。
import java.net.Socket;
import jdk.net.ExtendedSocketOptions;

Socket socket = new Socket();
socket.setOption(ExtendedSocketOptions.TCP_KEEPIDLE, 10);
socket.setOption(ExtendedSocketOptions.TCP_KEEPCOUNT, 2);
socket.setOption(ExtendedSocketOptions.TCP_KEEPINTERVAL, 3);

1
显然,这也在2020年针对某些平台(如Linux和Mac OS)回溯到了一些Java 8发行版。来源:https://bugs.openjdk.java.net/browse/JDK-8194298 和 https://mail.openjdk.java.net/pipermail/jdk8u-dev/2020-October/012817.html - JohannesB

4
给出的链接并没有告诉你如何使用 JNA 来实现它。在 Stack Overflow 上翻了一会儿之后,我自己写了一个库。你可以在这里找到它。

1
最近的Netty版本允许您使用epoll类型的通道,并设置Linux本地套接字选项,例如您提到的选项。
有关详细信息,请参见EpollChannelOption文档

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接