当我使用PuTTY等工具时,如果我的连接丢失(或者我在Windows上手动使用ipconfig /release
命令),它会直接响应并通知我连接丢失了。
我想创建一个Java程序来监视我的Internet连接(到一些可靠的服务器),以记录当我的互联网连接失败的日期/时间。
我尝试使用Socket.isConnected()
方法,但它将永远返回“true”。 我该如何在Java中实现这个功能?
当我使用PuTTY等工具时,如果我的连接丢失(或者我在Windows上手动使用ipconfig /release
命令),它会直接响应并通知我连接丢失了。
我想创建一个Java程序来监视我的Internet连接(到一些可靠的服务器),以记录当我的互联网连接失败的日期/时间。
我尝试使用Socket.isConnected()
方法,但它将永远返回“true”。 我该如何在Java中实现这个功能?
判断连接是否中断的最佳方法是尝试读取/写入套接字。如果操作失败,则说明连接已经中断。
因此,您只需要在一定时间间隔内尝试读取,如果读取失败则尝试重新连接。
对于您来说,重要的事件将是读取失败 - 您失去了连接,以及连接新套接字时 - 您重新获得了连接。
这样您就可以跟踪上线时间和下线时间。
read()
将返回 -1,readLine()
返回 null,对于任何其他 X 的 readXXX()
都会抛出 EOFException
。检测丢失的 TCP 连接的唯一可靠方法是向其写入数据。最终这将抛出一个 IOException
'connection reset',但由于缓冲区,至少需要写入两次才能抛出此异常。为什么不使用java.net.InetAddress
类的isReachable()
方法?
这个方法的工作原理取决于JVM的实现,但是:
典型的实现会使用ICMP ECHO REQUEST(如果可以获得特权),否则它将尝试在目标主机的7号端口上建立TCP连接(回显)。
如果您想保持一个持续开放的连接,以便在连接失败时可以看到它,您可以自己连接运行ECHO协议的服务器,而不是让isReachable()
为您执行此操作,并读取和写入数据并等待它失败。
isReachable()
完全无关。 - user207421好的,我终于让它与之配合工作了。
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();
}
不如我希望的那么干净,但如果我省略os.writeBytes(),它就无法工作。
你可能想尝试查看套接字超时间隔。使用短暂的超时时间(我相信默认值为“无限超时”),当主机变得不可达时,您可能能够捕获异常或其他错误。
Socket.java
类中的isConnected()
方法有点误导人。它并不告诉你套接字当前是否连接到远程主机(比如是否未关闭)。相反,它告诉你套接字是否曾经连接到远程主机。如果套接字能够连接到远程主机,即使该套接字被关闭后,此方法也会返回true
。要判断套接字当前是否打开,您需要检查isConnected()
返回true
且isClosed()
返回false
。
boolean connected = socket.isConnected() && !socket.isClosed();
isClosed() == false
,否则没有 JDK bug。 - user207421可能更简单的方法是连接到雅虎/谷歌或类似的地方。
URL yahoo = new URL("http://www.yahoo.com/");
URLConnection yc = yahoo.openConnection();
int dataLen = yc.getContentLength() ;
尼尔