我需要在现有的商业 Java 应用程序上激活 SO_KEEPALIVE,因为我的防火墙在一些不活动后会断开连接。我不拥有源代码,所以我无法更改它(当我拥有源代码时会很容易,只需添加 socket.setKeepAlive(true) )。所以我一直在寻找一些替代方案:
首先,我尝试使用 libkeepalive.so ( http://libkeepalive.sourceforge.net/ ),将其放入 de LD_PRELOAD 似乎适用于 telnet 和 nc 之类的东西,但是当我将它与我的 jrockit jvm 一起使用时,这个 LD_PRELOAD 是完全被忽略,并且每个套接字对象仍然在没有 SO_KEEPALIVE 的情况下被创建
然后我尝试在操作系统级别搜索是否有一个选项可以为所有 TCP 连接默认激活此 SO_KEEPALIVE:不幸的是,在 redhat 6 企业版上没有这样的选项,尽管我找到了一个用于 freebsd 的选项(net.inet.tcp .always_keepalive)
修补 linux 内核以添加此功能对我的系统管理员来说是一个很大的问题;)
搜索任何 java 命令行参数均不成功
所以最后一个选项:通过添加 setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(true)) 来修补现有 JVM 的 java.net.PlainSocketImpl;在受保护的同步 void create(boolean stream) 方法中,并通过 -Xbootclasspath/p 将其放在 rt.jar 之前
到目前为止,最后一个选项有效,但我有点沮丧,因为我不得不为此更改 JVM!任何人都知道其他/更好的方法来处理这样的问题?为什么没有另一种简单的方法可以在所有(java)应用程序上默认激活 SO_KEEPALIVE?
最后一个问题:为什么 java API 不允许您在 serverSockets 对象上设置 keepAlive?它只适用于 Socket 对象,但实际上它也适用于 serverSockets