Java检测丢失的连接

时间:2009-06-09 12:45:15

标签: java tcp connection

当我使用时,例如PuTTY和我的连接丢失(或者当我在Windows上进行手动ipconfig /release时),它会直接响应并通知我的连接丢失。

我想创建一个监控我的Internet连接(到一些可靠的服务器)的Java程序,以记录我的互联网发生故障时的日期/时间。

我尝试使用Socket.isConnected()方法,但这将永远返回“true”。我怎么能用Java做到这一点?

9 个答案:

答案 0 :(得分:20)

那么,判断连接是否中断的最佳方法是尝试从套接字读取/写入。如果操作失败,那么您有时会丢失连接。

因此,您需要做的就是尝试在某个时间间隔读取,如果读取失败,请尝试重新连接。

对于您来说,重要的事件是当读取失败时 - 您丢失连接,并且当连接新套接字时 - 您重新获得连接。

通过这种方式,您可以跟踪正常运行时间和停机时间。

答案 1 :(得分:11)

即使TCP / IP是“面向连接”协议,通常也不会通过空闲连接发送数据。您可以将套接字打开一年,而IP堆栈不会通过它发送一个套接字。为了注意连接丢失,您必须在应用程序级别发送一些数据。(*)您可以通过从ADSL调制解调器上拔下电话线来试试这个。除非应用程序具有某种应用程序级别的保持活动机制,否则PC中的所有连接都应保持运行。

因此,注意丢失连接的唯一方法是打开与某个服务器的TCP连接并从中读取一些数据。也许最简单的方法是连接到某个FTP服务器并偶尔获取一个小文件 - 或目录列表。我从未见过真正意味着用于这种情况的通用服务器,FTP服务器的所有者可能不喜欢客户端这样做。

(*)还有一种称为TCP keepalive的机制,但是在许多操作系统中你必须为所有应用程序激活它,如果你想快速注意到连接丢失,那么使用它是不切实际的

答案 2 :(得分:7)

为什么不使用java.net.InetAddress类的isReachable()方法?

这是如何工作的特定于JVM实现,但是:

  

如果可以获得权限,典型的实现将使用ICMP ECHO REQUEST,否则它将尝试在目标主机的端口7(Echo)上建立TCP连接。

如果你想连续打开一个连接,这样你就可以看到失败的时候你可以连接到自己运行ECHO protocol的服务器,而不是让isReachable()为你做这个并读取和写入数据等待它失败。

答案 3 :(得分:7)

如果客户端已正确断开连接,则read()将返回-1,readLine()将返回null,readXXX()表示任何其他X引发EOFException。检测丢失的TCP连接的唯一可靠方法是写入它。因此最终将抛出IOException'连接重置',但由于缓冲,它至少需要两次写入。

答案 4 :(得分:1)

您可能想尝试查看套接字timeout interval。如果短暂超时(我相信默认为'无限超时'),那么当主机无法访问时,您可能会捕获异常或其他内容。

答案 5 :(得分:1)

好的,所以我终于让它与

合作了
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(),它就无法正常工作。

答案 6 :(得分:0)

你可以每秒钟对一台机器执行ping操作,这非常准确。小心你没有DOS它。

另一种方法是在远程计算机上运行一个小型服务器并保持与它的连接。

答案 7 :(得分:0)

连接到雅虎/谷歌或者像这样的地方可能更简单。

    URL yahoo = new URL("http://www.yahoo.com/");
    URLConnection yc = yahoo.openConnection();
    int dataLen = yc.getContentLength() ;

尼尔

答案 8 :(得分:0)

Socket.java类中的isConnected()方法有点误导。它不会告诉您套接字当前是否连接到远程主机(如果它是未闭合的)。 相反,它会告诉您套接字是否曾连接到远程主机。如果套接字能够连接到远程主机,则此方法返回true,即使该套接字已关闭。要判断套接字当前是否已打开,您需要检查isConnected()是否返回trueisClosed()返回false。 例如:

boolean connected = socket.isConnected() && !socket.isClosed();