java.net.Socket TCP保持活动使用

java.net.Socket TCP保持活动使用,java,sockets,Java,Sockets,如何使用API 我正在使用Socket托管一个简单的服务器。 客户端可以连接和发送数据。除非客户端发送流结束,否则我不会关闭连接。客户端可以继续保持连接任意长度的时间。数据传输将继续进行,但我突然发现没有任何日志的连接丢失。重新启动客户端(而不是服务器)后,传输将再次开始。 我没有设置任何超时,因为默认情况下它是无限的。我想了解setKeepAlive的实际功能,以便我能够决定是否需要将其设置为true。 有人能帮我理解吗?谢谢。如的文档所述,它将启用(或禁用)套接字上的选项 如果为TCP套接字

如何使用API

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

如的文档所述,它将启用(或禁用)套接字上的选项

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

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



请注意,在网络中,由于各种原因,连接随时可能丢失。如果连接通过NAT路由器,NAT表中的条目可能会过期(当连接空闲时),并且连接因此而丢失。客户端可能会停止工作,或被暂停(尤其是笔记本电脑和移动设备),或电缆可能被断开,或WiFi(或蜂窝)信号可能受到干扰,或。。。这个名单还可以继续下去。您的服务器需要编写,以优雅地处理连接丢失。

在我的情况下,我面临类似的问题

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

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

在windows操作系统中,可以配置keepalive_time&keepalive_intvl,但不能更改tcp_keepalive_探测。默认情况下,初始化tcp套接字时,将保持活动超时设置为2小时,保持活动间隔设置为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\u keepalive结构的指针 (DWORD)cbInBuffer,//输入缓冲区的长度 NULL,//输出缓冲区 0,//输出缓冲区的大小 (LPDWORD)lpcbBytesReturned,//返回的字节数 NULL,//重叠结构 空//完成例程 );

Linux操作系统

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

int-setsockopt(int-socket、int-level、int-optname、, 施工无效*optval,socklen_t optlen)


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

也许你可以澄清到底是什么问题?可能会发布给你带来麻烦的代码。如果你不理解
setKeepAlive()
的功能,那么你怎么知道它解决了你的问题呢?嗨,我编辑了我的问题。嘿,谢谢你的解释。但是,如何在应用程序中编写代码来检查客户端是否处于活动状态等?@LPD要检查客户端是否处于活动状态,需要应用程序协议发送消息并期望响应。通常,无法知道TCP连接的远端是否处于“活动”状态。该程序可能暂时不需要发送任何东西,或者它可能已经消失(软件退出、硬件死机、断电、反铲损坏网络电缆等)。它不是强制性的。您需要决定您的协议是否合适。文档不正确。插座未关闭。应用程序仍然必须关闭它。连接已重置,对其进行的下一次I/O操作将抛出一个
IOException
。请不要在多个旧问题中持续发布相同的答案。如果您认为它们是重复的,则将其标记为重复。