重新连接Java套接字连接以解决断开连接问题

6

我有一段Java代码,它建立了一个长期的socket连接以监视家庭自动化设备的活动/事件。问题是,如果设备重新启动或断电,Java代码应尽快自动重新连接。有什么想法可以在Java端检测到连接中断,最好不需要定期轮询设备?

3个回答

3
如果设备在没有正确关闭套接字的情况下重新启动,我不知道是否有什么方法可以让您检测到。除非设备重新启动或者TCP/IP协议栈放弃并声明连接已断开,否则您的服务器将无法检测到套接字已经失效。最终,您将收到一个IOException异常。您需要在出现此异常时捕获它,然后重新连接。
在这里,您真的取决于TCP/IP的行为。当连接的一端突然消失(没有FIN数据包)时,另一端可能会等待任意长的时间(取决于许多因素)才能确定连接已经断开。
如果您想更早地发现这个问题,并且可以保证设备在一定时间内响应,则应该在套接字上设置超时。如果这样做,如果设备不响应,您将收到一个SocketTimeoutException异常,然后您可以关闭套接字并尝试重新打开套接字。我已经成功使用过这种方法。

2
如果您的软件只是等待来自家庭自动化设备的数据,那么检测该设备是否离线的唯一方法是在与该设备通信的套接字打开时启用SO_KEEPALIVE选项。
要做到这一点,只需在套接字上调用setKeepAlive(true)方法即可,这将使底层套接字实现启用SO_KEEP_ALIVE选项。
这将使底层实现定期与远程端点交换一些数据,并且如果在等待数据时设备死机,则会抛出异常。
唯一的问题是这个保持活动时间取决于操作系统,有时无法更改。
如果您需要更短的超时时间,除了在设备上实现周期性探测之外,没有其他办法。

1

我已经解决了这个完全相同的问题。

如果你想要更早地捕获这个问题——并且你可以保证设备在一定时间内会响应,那么就在套接字上设置一个超时。如果这样做,如果设备没有响应,你将得到一个SocketTimeoutException,然后你可以关闭套接字并尝试重新打开套接字。我已经成功地使用了这个方法。

引用自上文:

我让它关闭套接字,然后尝试重新打开它,这段代码运行得很好。唯一的问题是,一旦我关闭了一个套接字,我就无法重新打开它,我会得到套接字已关闭的异常。这种情况每次都发生。如何关闭套接字,然后重新打开它而不出现这个异常?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接