简体   繁体   English

java.net.Socket TCP keep-alive用法

[英]java.net.Socket TCP keep-alive usage

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

I am hosting a simple server using Socket . 我正在使用Socket托管一个简单的服务器。 The clients can connect and send data. 客户端可以连接和发送数据。 I will not close the connection unless the client sends end of stream. 除非客户端发送流结束,否则我不会关闭连接。 The client can continue to hold a connection for any length of time. 客户端可以继续保持连接任何时间长度。 Data transfer will be going on, but suddenly I see that there is a connection loss without any logs whatsoever. 数据传输将继续进行,但突然间我发现连接丢失没有任何日志。 Once the client is restarted (not server), the transmission begins again. 重新启动客户端(而不是服务器)后,传输将再次开始。 I am not setting any timeout as by default it is infinity. 我没有设置任何timeout ,因为默认情况下它是无穷大。 I want to understand what setKeepAlive actually does so that I will be able to decide whether I need to set that to true . 我想了解setKeepAlive实际上做了什么,以便我能够决定是否需要将其设置为true Can someone help me understand the same? 有人可以帮我理解吗? thanks. 谢谢。

As the documentation for setKeepAlive() says, it will enable (or disable) the SO_KEEPALIVE option on the socket. 正如setKeepAlive()的文档所说,它将启用(或禁用)套接字上的SO_KEEPALIVE选项。

When the keepalive option is set for a TCP socket and no data has been exchanged across the socket in either direction for 2 hours (NOTE: the actual value is implementation dependent), TCP automatically sends a keepalive probe to the peer. 当为TCP套接字设置keepalive选项并且在任一方向上没有跨套接字交换数据2小时时(注意:实际值取决于实现),TCP会自动向对等方发送keepalive探测。 This probe is a TCP segment to which the peer must respond. 此探测是对等方必须响应的TCP段。 One of three responses is expected: 1. The peer responds with the expected ACK. 预期三个响应之一:1。对等体响应预期的ACK。 The application is not notified (since everything is OK). 未通知应用程序(因为一切正常)。 TCP will send another probe following another 2 hours of inactivity. 在另外2小时不活动之后,TCP将发送另一个探测。 2. The peer responds with an RST, which tells the local TCP that the peer host has crashed and rebooted. 2.对等体使用RST响应,该RST告知本地TCP对等主机已崩溃并重新启动。 The socket is closed. 插座已关闭。 3. There is no response from the peer. 3.同行没有回应。 The socket is closed. 插座已关闭。 The purpose of this option is to detect if the peer host crashes. 此选项的目的是检测对等主机是否崩溃。 Valid only for TCP socket: SocketImpl 仅对TCP套接字有效:SocketImpl

Here is another reference explaining the SO_KEEPALIVE option. 是另一个解释SO_KEEPALIVE选项的参考。


Note that in networking, connections can be lost at any time for a myriad of reasons. 请注意,在网络中,由于种种原因,连接可能随时丢失。 If the connection traverses a NAT router, the entry in the NAT table could expire (when the connection is idle) and the connection is lost due to that. 如果连接遍历NAT路由器,则NAT表中的条目可能会过期(当连接空闲时),并且连接因此而丢失。 The client could cease to function, or be suspended (especially laptops and mobile devices), or a cable could be disconnected, or WiFi (or cellular) signal could be interfered with, or ... the list can go on. 客户端可能停止运行或被暂停(特别是笔记本电脑和移动设备),或者电缆可能断开连接,或者WiFi(或蜂窝)信号可能受到干扰,或者...列表可以继续。 Your server needs to be written to cope gracefully with loss of connection. 您的服务器需要编写才能正常处理连接丢失。

I face the similar problem in my case 在我的情况下,我面临类似的问题

In JAVA Socket – TCP connections are managed on the OS level, java.net.Socket does not provide any in-built function to set timeouts for keepalive packet on a per-socket level. 在JAVA套接字中 - 在OS级别上管理TCP连接,java.net.Socket不提供任何内置函数来为每个套接字级别设置keepalive数据包的超时。 But we can enable keepalive option for java socket but it takes 2 hours 11 minutes (7200 sec) by default to process after a stale tcp connections. 但是我们可以为java socket启用keepalive选项,但默认情况下需要2小时11分钟(7200秒)来处理过时的tcp连接。 This cause connection will be availabe for very long time before purge. 这种原因连接在清除之前可以使用很长时间。 So we found some solution to use Java Native Interface (JNI) that call native code(c++) to configure these options. 所以我们找到了一些解决方案来使用调用本机代码(c ++)的Java Native Interface(JNI)来配置这些选项。

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

In windows operating system keepalive_time & keepalive_intvl can be configurable but tcp_keepalive_probes cannot be change.By default, when a TCP socket is initialized sets the keep-alive timeout to 2 hours and the keep-alive interval to 1 second. 在Windows操作系统中,keepalive_time和keepalive_intvl可以配置,但tcp_keepalive_probes不能更改。默认情况下,初始化TCP套接字时,将保持活动超时设置为2小时,将保持活动时间间隔设置为1秒。 The default system-wide value of the keep-alive timeout is controllable through the KeepAliveTime registry setting which takes a value in milliseconds. 保持活动超时的默认系统范围值可通过KeepAliveTime注册表设置控制,该设置采用以毫秒为单位的值。

On Windows Vista and later, the number of keep-alive probes (data retransmissions) is set to 10 and cannot be changed. 在Windows Vista及更高版本中,保持活动探测(数据重新传输)的数量设置为10,无法更改。

On Windows Server 2003, Windows XP, and Windows 2000, the default setting for number of keep-alive probes is 5. The number of keep-alive probes is controllable. 在Windows Server 2003,Windows XP和Windows 2000上,保持活动探测数的默认设置为5.保持活动探测的数量是可控的。 For windows Winsock IOCTLs library is used to configure the tcp-keepalive parameters. 对于Windows,Winsock IOCTLs库用于配置tcp-keepalive参数。

int WSAIoctl( SocketFD, // descriptor identifying a socket SIO_KEEPALIVE_VALS, // dwIoControlCode (LPVOID) lpvInBuffer, // pointer to tcp_keepalive struct (DWORD) cbInBuffer, // length of input buffer NULL, // output buffer 0, // size of output buffer (LPDWORD) lpcbBytesReturned, // number of bytes returned NULL, // OVERLAPPED structure NULL // completion routine ); int WSAIoctl(SocketFD,//标识套接字的描述符SIO_KEEPALIVE_VALS,// dwIoControlCode(LPVOID)lpvInBuffer,//指向tcp_keepalive结构的指针(DWORD)cbInBuffer,//输入缓冲区长度NULL,//输出缓冲区0,//大小输出缓冲区(LPDWORD)lpcbBytesReturned,//返回的字节数为NULL,// OVERLAPPED结构为NULL //完成例程);

Linux OS Linux操作系统

Linux has built-in support for keepalive which is need to be enabling TCP/IP networking in order to use it. Linux内置了对keepalive的支持,需要启用TCP / IP网络才能使用它。 Programs must request keepalive control for their sockets using the setsockopt interface. 程序必须使用setsockopt接口请求对其套接字进行keepalive控制。

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

Each client socket will be created using java.net.Socket. 每个客户端套接字都将使用java.net.Socket创建。 File descriptor ID for each socket will retrieve using java reflection. 每个套接字的文件描述符ID将使用java反射进行检索。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM