java.net.Socket TCP keep-alive usage



如何使用java.net.Socket setKeepAlive(boolean b) API?

我正在使用Socket托管一个简单的服务器。客户端可以连接和发送数据。除非客户端发送流结束,否则我不会关闭连接。客户端可以继续保持任何时间长度的连接。数据传输将继续进行,但突然我看到有一个连接丢失,没有任何日志。一旦客户机重新启动(而不是服务器),传输将再次开始。我没有设置任何timeout,因为默认情况下它是无穷大。我想了解setKeepAlive实际上做了什么,以便我能够决定是否需要将其设置为true。有人能帮我理解吗?谢谢。

正如setKeepAlive()的文档所说,它将启用(或禁用)套接字上的SO_KEEPALIVE选项。

当为TCP套接字设置了keepalive选项,并且在两个小时(注:实际值取决于实现)内没有任何数据交换时,TCP将自动向对端发送keepalive探测。该探测是一个TCP段,对等体必须对其进行响应。预计会有以下三种反应之一:对等体以预期的ACK响应。不会通知应用程序(因为一切正常)。TCP将在另一个2小时不活动后发送另一个探测。2. 对端响应一个RST,告诉本地TCP对端主机已经崩溃并重新启动。套接字已关闭。3.对端没有响应。处理步骤套接字已关闭。此选项的目的是检测对等主机是否崩溃。仅对TCP套接字有效:SocketImpl

这是另一个解释SO_KEEPALIVE选项的参考。


请注意,在网络中,由于各种原因,连接可能随时丢失。如果连接经过NAT路由器,则NAT表中的条目可能会过期(当连接处于空闲状态时),从而导致连接丢失。客户端可能会停止工作,或者被挂起(尤其是笔记本电脑和移动设备),或者电缆可能会断开,或者WiFi(或蜂窝)信号可能会受到干扰,或者……这样的例子不胜枚举。您的服务器需要被编写为能够优雅地处理连接丢失

我也面临着类似的问题

在JAVA Socket - TCP连接是在操作系统级别管理的,socket没有提供任何内置函数来在每个套接字级别上设置keepalive数据包的超时时间。但是我们可以为java套接字启用keepalive选项,但是在默认情况下,处理一个失效的tcp连接需要2小时11分钟(7200秒)。在吹扫之前,这种原因连接将可用很长时间。因此,我们找到了一些解决方案,使用Java本机接口(JNI)调用本机代码(c++)来配置这些选项。

* * * * Windows操作系统* * * *

windows操作系统keepalive_time &Keepalive_intvl可以配置,但tcp_keepalive_probes不能更改。缺省情况下,TCP套接字初始化时,保持连接超时时间为2小时,保持连接间隔为1秒。默认的系统范围的keep-alive超时值可以通过KeepAliveTime注册表设置来控制,该注册表的值以毫秒为单位。

在Windows Vista及更高版本中,keep-alive探测(数据重传)的数量被设置为10,并且不能更改。

在Windows Server 2003、Windows XP和Windows 2000中,默认设置的keep-alive探测数为5。keep-alive探针的数量是可控的。对于windows, Winsock IOCTLs库用于配置tcp-keepalive参数。

int WSAIoctl (SocketFD,//标识套接字的描述符SIO_KEEPALIVE_VALS,//dwIoControlCode(LPVOID) lpvInBuffer,//tcp_keepalive结构指针cbInBuffer,//输入缓冲区的长度NULL,//输出缓冲区0,//输出缓冲区的大小(LPDWORD) lpcbBytesReturned,//返回字节数NULL,//重叠结构NULL//完成例程);

Linux操作系统

Linux有内置的keepalive支持,需要启用TCP/IP网络才能使用它。程序必须使用setsockopt接口请求其套接字的keepalive控制。

int setsockopt(int socket, int level, int optname,Const void *optval, socklen_t optlen)

每个客户端套接字将使用java.net.Socket创建。每个套接字的文件描述符ID将使用java反射检索。

最新更新