断开连接时重新连接 Java 套接字连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/954064/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:33:16  来源:igfitidea点击:

Reconnect a Java socket connection on disconnect

javasockets

提问by

I've got Java code which makes a long term socket connection to a home automation device to monitor it for activity/events. The problem is if the device is rebooted or gets power cycled the Java code should automatically reconnect as soon as possible. Any ideas for how to detect a dropped connection on the Java side, preferably without periodic polling the device?

我有 Java 代码,它与家庭自动化设备建立长期套接字连接,以监视它的活动/事件。问题是,如果设备重新启动或重新启动,Java 代码应尽快自动重新连接。关于如何检测 Java 端连接断开的任何想法,最好不要定期轮询设备?

回答by Eddie

If the device reboots without properly closing the socket, I don't know of anything that will allow you to detect it. Your server will not be able to detect that the socket has gone away, in this case, unless the device comes back up or until the TCP/IP stack on your server gives up and declares the connection is dead. At some point you'll get an IOException.You need to catch that Exception and then reconnect when it occurs.

如果设备在没有正确关闭套接字的情况下重新启动,我不知道有什么可以让您检测到它。在这种情况下,您的服务器将无法检测到套接字已消失,除非设备恢复正常或直到您服务器上的 TCP/IP 堆栈放弃并声明连接已失效。在某些时候你会得到一个IOException.You need to catch that Exception 然后在它发生时重新连接。

You're really at the mercy of the behavior of TCP/IP here. When one end of a connection simply disappears (no FINpacket), the other end may wait an arbitrary length of time (depending on many factors) before deciding the connection is dead.

您在这里真的受 TCP/IP 行为的支配。当连接的一端简单地消失(没有FIN数据包)时,另一端可能会等待任意长度的时间(取决于许多因素),然后才决定连接已死。

If you want to catch this problem earlier -- and you can guarantee that the device will respond within a set amount of time, then set a timeout on the socket. If you do this, you'll get a SocketTimeoutExceptionif the device doesn't respond, and you can then close the socket and try reopening the socket. I have used this with success.

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

回答by Reginaldo

If your software is just waiting for data from the home automation device the only way to detect that the device is gone is to enable the SO_KEEPALIVE option in the socket open to communicate with the device.

如果您的软件只是在等待来自家庭自动化设备的数据,那么检测设备已消失的唯一方法是在打开的套接字中启用 SO_KEEPALIVE 选项以与设备进行通信。

To do this just call setKeepAlive(true) method on the socket and that will make the underlying socket implementation enable the SO_KEEP_ALIVE option.

为此,只需在套接字上调用 setKeepAlive(true) 方法,这将使底层套接字实现启用 SO_KEEP_ALIVE 选项。

This will make the underlying implementation periodically exchange some data with the remote endpoint and if the device dies while you are waiting for data, an exception will be thrown.

这将使底层实现定期与远程端点交换一些数据,如果设备在您等待数据时死机,则会引发异常。

The only problem is that this keep alive time-out depends on the operating system and sometimes cannot be changed.

唯一的问题是这种保持活动超时取决于操作系统,有时无法更改。

If you need shorter timeouts, there's no other way than implementing a periodic probe on the device.

如果您需要更短的超时时间,除了在设备上实施定期探测之外别无他法。

回答by GregHaki

I have solved this exact same problem.

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

If you want to catch this problem earlier -- and you can guarantee that the device will respond within a set amount of time, then set a timeout on the socket. If you do this, you'll get a SocketTimeoutException if the device doesn't respond, and you can then close the socket and try reopening the socket. I have used this with success.

如果你想更早地发现这个问题——并且你可以保证设备会在设定的时间内响应,然后在套接字上设置超时。如果您这样做,如果设备没有响应,您将收到 SocketTimeoutException,然后您可以关闭套接字并尝试重新打开套接字。我已经成功地使用了它。

Quoted from above:

引自上面:

I get it to close the socket then attempt to reopen it, which it runs that code fine. The only problem is that once I close a socket I cannot reopen it, I get the exception that the socket is closed. This happens every time. How do I close a socket then reopen it with out getting this exception?

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