我遇到了类似的问题
在 JAVA Socket 中 – TCP 连接在操作系统级别进行管理,
java.net.Socket 不提供任何内置函数来为每个套接字级别的 keepalive 数据包设置超时。
但是我们可以为 java socket 启用 keepalive 选项,但默认情况下需要 2 小时 11 分钟(7200 秒)来处理陈旧的 tcp 连接。
在清除之前,此原因连接将可用很长时间。
所以我们找到了一些解决方案,使用 Java Native Interface (JNI) 调用原生代码(c++) 来配置这些选项。
****Windows 操作系统****
在windows操作系统中keepalive_time & keepalive_intvl 可以配置,但tcp_keepalive_probes不能改变。默认情况下,初始化TCP套接字时将keepalive超时设置为2小时,keepalive间隔设置为1秒。保持活动超时的默认系统范围值可通过 KeepAliveTime 注册表设置进行控制,该设置以毫秒为单位。
在 Windows Vista 及更高版本上,keep-alive 探测(数据重新传输)的数量设置为 10 且无法更改。
在 Windows Server 2003、Windows XP 和 Windows 2000 上,keep-alive probes 的默认设置为 5。keep-alive probes 的数量是可控的。
对于 windows Winsock IOCTLs 库用于配置 tcp-keepalive 参数。
int WSAIoctl(
SocketFD, // 标识套接字的描述符
SIO_KEEPALIVE_VALS, // dwIoControlCode
(LPVOID) lpvInBuffer, // 指向 tcp_keepalive 结构的指针
(DWORD) cbInBuffer, // 输入缓冲区的长度
NULL, // 输出缓冲区
0, // 输出缓冲区大小
(LPDWORD) lpcbBytesReturned, // 返回的字节数
NULL, // 重叠结构
NULL // 完成例程
);
Linux 操作系统
Linux 内置了对 keepalive 的支持,需要启用 TCP/IP 网络才能使用它。程序必须使用 setsockopt 接口为其套接字请求保持活动控制。
int setsockopt(int socket, int level, int optname,
const void *optval, socklen_t optlen)
每个客户端套接字都将使用 java.net.Socket 创建。每个套接字的文件描述符 ID 将使用 java 反射检索。