java.net.Socket TCP keep-alive用法

时间:2015-08-04 13:28:54

标签: java sockets

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

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

2 个答案:

答案 0 :(得分:3)

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

  

如果为TCP套接字设置了keepalive选项,并且在任何方向上没有数据在套接字上交换2小时(注意:实际值取决于实现),TCP会自动向对等方发送keepalive探测。此探测是对等方必须响应的TCP段。预期三个响应之一:1。对等体响应预期的ACK。未通知应用程序(因为一切正常)。在另外2小时不活动之后,TCP将发送另一个探测。 2.对等体使用RST响应,该RST告知本地TCP对等主机已崩溃并重新启动。插座已关闭。 3.同行没有回应。插座已关闭。此选项的目的是检测对等主机是否崩溃。仅对TCP套接字有效:SocketImpl

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

请注意,在网络中,由于种种原因,连接可能随时丢失。如果连接遍历NAT路由器,则NAT表中的条目可能会过期(当连接空闲时),并且连接因此而丢失。客户端可能停止运行或被暂停(特别是笔记本电脑和移动设备),或者电缆可能断开连接,或者WiFi(或蜂窝)信号可能被干扰,或者...列表可以继续。您需要编写服务器以妥善处理连接丢失。

答案 1 :(得分:0)

我遇到类似的问题

在JAVA套接字中-TCP连接在操作系统级别进行管理, java.net.Socket不提供任何内置功能来为每个套接字级别的keepalive数据包设置超时。 但是我们可以为java套接字启用keepalive选项,但是默认情况下,在过时的tcp连接之后,它需要2小时11分钟(7200秒)才能处理。 在吹扫之前,这会导致连接很长一段时间。 因此,我们找到了一种使用Java本机接口(JNI)的解决方案,该解决方案调用本机代码(c ++)来配置这些选项。

**** Windows OS ****

在Windows操作系统中,keepalive_time和keepalive_intvl可以配置,但是tcp_keepalive_probes无法更改。默认情况下,初始化TCP套接字时,将keep-alive超时设置为2小时,而keep-alive间隔设置为1秒。保持活动超时的系统范围默认值可以通过KeepAliveTime注册表设置来控制,该设置以毫秒为单位。

在Windows Vista和更高版本上,保持活动状态探测(数据重新传输)的数量设置为10,并且无法更改。

在Windows Server 2003,Windows XP和Windows 2000上,保持活动探针的默认设置为5。保持活动探针的数量是可控制的。 对于Windows,Winsock IOCTLs库用于配置tcp-keepalive参数。

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

Linux操作系统

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

int setsockopt(int套接字,int级别,int optname,                  const void * optval,socklen_t optlen)

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