Java检测丢失的连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/969866/
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
Java detect lost connection
提问by kresjer
When I'm using e.g. PuTTY and my connection gets lost (or when I do a manual ipconfig /releaseon Windows), it responds directly and notifies my connection was lost.
当我使用 PuTTY 并且我的连接丢失时(或者当我ipconfig /release在 Windows 上执行手册时),它会直接响应并通知我的连接丢失。
I want to create a Java program which monitors my Internet connection (to some reliable server), to log the date/times when my internet fails.
我想创建一个 Java 程序来监视我的 Internet 连接(到一些可靠的服务器),以在我的 Internet 出现故障时记录日期/时间。
I tried use the Socket.isConnected()method but that will just forever return "true". How can I do this in Java?
我尝试使用该Socket.isConnected()方法,但这将永远返回“true”。我怎样才能在 Java 中做到这一点?
采纳答案by jjnguy
Well, the best way to tell if your connection is interrupted is to try to read/write from the socket. If the operation fails, then you have lost your connection sometime.
好吧,判断您的连接是否中断的最佳方法是尝试从套接字读取/写入。如果操作失败,则您在某个时候失去了连接。
So, all you need to do is to try reading at some interval, and if the read fails try reconnecting.
因此,您需要做的就是尝试每隔一段时间读取一次,如果读取失败,请尝试重新连接。
The important events for you will be when a read fails - you lost connection, and when a new socket is connected - you regained connection.
对您而言重要的事件将是读取失败时 - 您失去连接,以及连接新套接字时 - 您重新获得连接。
That way you can keep track of up time and down time.
这样您就可以跟踪正常运行时间和停机时间。
回答by Dave Webb
Why not use the isReachable()method of the java.net.InetAddressclass?
为什么不使用类的isReachable()方法java.net.InetAddress呢?
How this works is JVM implementation specific but:
它的工作原理是特定于 JVM 实现的,但是:
A typical implementation will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to establish a TCP connection on port 7 (Echo) of the destination host.
如果可以获得特权,典型的实现将使用 ICMP ECHO REQUEST,否则它将尝试在目标主机的端口 7(Echo)上建立 TCP 连接。
If you want to keep a connection open continually so you can see when that fails you could connect to server running the ECHO protocolyourself rather than having isReachable()do it for you and read and write data and wait for it to fail.
如果您想保持连接持续打开以便您可以看到何时失败,您可以自己连接到运行ECHO 协议的服务器,而不是isReachable()为您这样做并读取和写入数据并等待它失败。
回答by Geo
You could ping a machine every number of seconds, and this would be pretty accurate. Be careful that you don't DOS it.
您可以每隔几秒 ping 一次机器,这将非常准确。小心你不要DOS它。
Another alternative would be run a small server on a remote machine and keep a connection to it.
另一种选择是在远程机器上运行一个小型服务器并保持与它的连接。
回答by Neil Wightman
Its probably simpler to connect to yahoo/google or somewhere like this.
连接到 yahoo/google 或类似的地方可能更简单。
URL yahoo = new URL("http://www.yahoo.com/");
URLConnection yc = yahoo.openConnection();
int dataLen = yc.getContentLength() ;
Neil
尼尔
回答by poundifdef
You might want to try looking at the socket timeout interval. With a short timeout (I believethe default is 'infinite timeout') then you might be able to trap an exception or something when the host becomes unreachable.
您可能想尝试查看套接字超时时间间隔。如果超时时间很短(我相信默认值为“无限超时”),那么当主机无法访问时,您可能会捕获异常或其他内容。
回答by tputkonen
Even though TCP/IP is "connection oriented" protocol, normally no data is sent over an idle connection. You can have a socket open for a year without a single bit sent over it by the IP stack. In order to notice that a connection is lost, you have to send some data on the application level.(*) You can try this out by unplugging the phone cable from your ADSL modem. All connections in your PC should stay up, unless the applications have some kind of application level keepalive mechanism.
即使 TCP/IP 是“面向连接”的协议,通常也不会通过空闲连接发送数据。您可以将套接字打开一年,而 IP 堆栈不会通过它发送任何比特。为了注意到连接丢失,您必须在应用程序级别发送一些数据。(*) 您可以通过从 ADSL 调制解调器上拔下电话线来尝试此操作。除非应用程序具有某种应用程序级别的保活机制,否则您 PC 中的所有连接都应该保持连接。
So the only way to notice lost connection is to open TCP connection to some server and read some data from it. Maybe the most simple way could be to connect to some FTP server and fetch a small file - or directory listing - once in a while. I have never seen a generic server which was really meant to be used for this case, and owners of the FTP server may not like clients doing this.
因此,注意到丢失连接的唯一方法是打开与某些服务器的 TCP 连接并从中读取一些数据。也许最简单的方法可能是连接到某个 FTP 服务器并偶尔获取一个小文件 - 或目录列表。我从未见过真正用于这种情况的通用服务器,并且 FTP 服务器的所有者可能不喜欢客户端这样做。
(*) There is also a mechanism called TCP keepalive but in many OS's you have to activate it for all applications, and it is not really practical to use if you want to notice loss of connection quickly
(*) 还有一种称为 TCP keepalive 的机制,但在许多操作系统中,您必须为所有应用程序激活它,如果您想快速发现连接丢失,使用它是不切实际的
回答by kresjer
Okay so I finally got it working with
好的,所以我终于可以使用它了
try
{
Socket s = new Socket("stackoverflow.com",80);
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(s.getInputStream());
while (true)
{
os.writeBytes("GET /index.html HTTP/1.0\n\n");
is.available();
Thread.sleep(1000);
}
}
catch (IOException e)
{
System.out.println("connection probably lost");
e.printStackTrace();
}
Not as clean as I hoped but it's not working if I leave out the os.writeBytes().
不像我希望的那么干净,但如果我省略 os.writeBytes(),它就不起作用。
回答by user207421
If the client has disconnects properly, a read()will return -1, readLine()returns null, readXXX()for any other X throws EOFException. The only reliable way to detect a lost TCP connection is to write to it. Eventually thus will throw an IOException'connection reset', but it takes at least two writes due to buffering.
如果客户端正确断开连接,对于任何其他 X throws ,aread()将返回 -1,readLine()返回 null 。检测丢失的 TCP 连接的唯一可靠方法是写入它。最终因此将引发“连接重置”,但由于缓冲,它至少需要两次写入。readXXX()EOFExceptionIOException
回答by Alboz
The isConnected()method inside Socket.java class is a little misleading. It does not tell you if the socket is currently connected to a remote host (like if it is unclosed). Instead, it tells you whether the socket has ever been connected to a remote host. If the socket was able to connect to the remote host at all, this method returns true, even after that socket has been closed. To tell if a socket is currently open, you need to check that isConnected()returns trueand isClosed()returns false.
For example:
isConnected()Socket.java 类中的方法有点误导。它不会告诉您套接字当前是否已连接到远程主机(例如它是否未关闭)。相反,它会告诉您套接字是否曾经连接到远程主机。如果套接字能够连接到远程主机true,即使在该套接字已关闭之后,该方法也会返回。要判断套接字当前是否打开,您需要检查isConnected()返回true和isClosed()返回false。例如:
boolean connected = socket.isConnected() && !socket.isClosed();

