java - 现有 java 应用程序上的 SO_KEEPALIVE

标签 java sockets kernel keep-alive ld-preload

我需要在现有的商业 java 应用程序上激活 SO_KEEPALIVE,因为我的防火墙在一段不活动后会断开连接。我不拥有源代码,所以我无法更改它(当我拥有源代码时,这会相当容易,只需添加 socket.setKeepAlive(true) )。所以我正在寻找一些替代方案:

  • 首先我尝试使用 libkeepalive.so ( http://libkeepalive.sourceforge.net/ ),将其放入 LD_PRELOAD 似乎适用于 telnet 和 nc 之类的东西,但是当我将它与我的 jrockit jvm 一起使用时,这个 LD_PRELOAD 完全是被忽略,并且仍在创建没有 SO_KEEPALIVE 的每个套接字对象

  • 然后我尝试在操作系统级别搜索是否有一个选项可以为所有 TCP 连接默认激活此 SO_KEEPALIVE:不幸的是,在 redhat 6 enterprise 上没有这样的选项,尽管我找到了一个用于 freebsd 的选项(net.inet.tcp.always_keepalive)

  • 修补 Linux 内核以添加此功能对我的系统管理员来说是一个很大的拒绝;)

  • 搜索任何 java 命令行参数均失败

  • 最后一个选项:通过添加 setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(true)); 来修补现有 JVM 的 java.net.PlainSocketImpl在 protected Synchronized void create(boolean stream) 方法中,并通过 -Xbootclasspath/p 将其放在 rt.jar 之前

最后一个选项到目前为止有效,但我有点沮丧,因为我必须为此更改 JVM!有人知道其他/更好的方法来处理这样的问题吗?为什么没有另一种简单的方法来在所有(java)应用程序上默认激活 SO_KEEPALIVE ?

最后一个问题:为什么 java API 不允许您在 serverSockets 对象上设置 keepAlive?它只能在 Socket 对象上使用,但实际上它也可以在 serverSockets 上使用

最佳答案

我遇到了同样的问题,想知道为什么 libkeepalive 不起作用。经过一番调查后,我发现 libkeepalive 有一些“局限性”(也许有人会称它们为错误)。 由于奇怪的许可证(它带有 GPL),我决定重新开始。结果是 libdontdie 。 您可以在那里找到一个可以与(至少)openjdk7 一起使用的小型 Java 测试程序。

关于java - 现有 java 应用程序上的 SO_KEEPALIVE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16127108/

相关文章:

java - 使用 Google Java API 设置单元格背景颜色和文本大小

java - HttpPost : InputDispatcher: "Channel is unrecoverably broken and will be disposed!" on Nexus 7

c - 编写 C 套接字 readline() 函数

linux - 树莓派 3 上的 ftrace + addr2line

linux - 在 Linux 工作队列中休眠

c - 在异常处理程序中创建的 Linux 内核线程停止

JavaFX listview 使用线程在自定义单元格中加载错误的图像

java - 日期格式并将该日期转换为 JodaTime

c - "no newline at end of file"C

java - 两个 socket 仅用于一个连接