用于测试internet连接的Java程序

用于测试internet连接的Java程序,java,sockets,Java,Sockets,我正在尝试编写一个简单的程序,实时告诉我是否连接了互联网。这就是我正在做的: import java.net.Socket; public class InternetConnection { public static void main(String[] args) { String inetAddress = "www.google.com"; int port = 80; while (true) { t

我正在尝试编写一个简单的程序,实时告诉我是否连接了互联网。这就是我正在做的:

import java.net.Socket;

public class InternetConnection {
    public static void main(String[] args) {
        String inetAddress = "www.google.com";
        int port = 80;

        while (true) {
            try {
                Socket socket = new Socket(inetAddress, port);
                System.out.println("Connected to the internet");
            } catch (Exception e) {
                System.out.println("Not connected to the internet");
            }
        }
    }
}
如果到达www.google.com,它会打印出所需的消息。但是,如果我故意断开与internet的连接以检查其是否工作,则它不会打印未连接到internet的信息,然后我重新连接并显示已连接到internet,但当我再次断开连接时,它仍显示已连接到internet的信息。我不知道我做错了什么


另外,我知道这不是检查是否有internet连接的最佳方法。

在创建套接字并打印连接消息后,请放置一段延迟时间

try {
    Socket socket = new Socket(inetAddress,port);
    System.out.println("Connected to the internet");
}catch(Exception e){      
    System.out.println("Not connected to the internet"); 
}
TimeUnit.SECONDS.sleep(5);

你的程序应该按预期工作。

你会得到未知的后异常,因为如果你尝试连接并拔出插头,谷歌的DNS查找将失败。如果您没有到主机的路由,它也应该直接抛出。在您的代码中,您没有超时处理,您至少应该使用可以提供给套接字构造函数的连接超时参数,尽管许多问题会直接抛出更多细节,例如这里。此外,您的单个运行时线程在出现问题时被阻塞,它将挂起在您的

Socket socket = new Socket(inetAddress, port); 
通常情况下,插座和互联网连接会出现问题。。您希望能够以一种受控的方式结束执行,或者也可以在一个单独的线程中运行您的程序,您可以以受控的方式停止该线程,并且您可能希望安排测试,而不仅仅是睡眠,比如

private final static ScheduledExecutorService scheduler = 
Executors.newScheduledThreadPool(1);
    ..
        Runnable r = () -> {
            try {
                testConnections();
            } catch (InterruptedException | ExecutionException | TimeoutException e) {
                // HANDLE IT
            }
        };
        scheduler.scheduleAtFixedRate(r, secondsInBetweenPolls, secondsInBetweenPolls, TimeUnit.SECONDS);
        }
    ..
private void testConnections() throws InterruptedException, ExecutionException, TimeoutException {
    for (URL u : urls) {
        if (isRunning){
            try{
                CompletableFuture.supplyAsync(() -> testConnection(u)).acceptEither(timeoutAfter(millisConnectionTimeOut, TimeUnit.MILLISECONDS), result -> currentStatus = result).get();
            } catch (Exception e) {
                if (e instanceof TimeoutException) {
                    currentStatus = Result.INTERNET_UNREACHABLE;
                }
            }
            if (currentStatus.equals(Result.INTERNET_REACHED)) {
                break; // first actual internet hit is enough, right?
            }
         }
     }
     notifyListener();
     lastStatus = currentStatus;
}

private void notifyListener() {
    if (lastStatus == null || !currentStatus.equals(lastStatus)) {
        if (currentStatus.equals(Result.INTERNET_REACHED)) {
            listener.connectionIsUp();
        } else {
            listener.connectionIsDown();
        }
    }
}

private Result testConnection(URL url) {
    if (isRunning) {
        HttpURLConnection urlConnect = null;
        try {
            urlConnect = (HttpURLConnection) url.openConnection();
            urlConnect.setConnectTimeout(millisConnectionTimeOut);
            int resultCode = urlConnect.getResponseCode();
            if (resultCode == 200) {
               return Result.INTERNET_REACHED;
            }
         } catch (IOException ignore) {}
     } finally {
             if (urlConnect != null) {
                 urlConnect.disconnect();
             }
         }
    }
    return Result.INTERNET_UNREACHABLE;
}
此外,我会追求一个完整的未来,它是无阻塞的,非常适合这种东西-你可以在这里阅读它,例如:。那么主要的区块可能是

private final static ScheduledExecutorService scheduler = 
Executors.newScheduledThreadPool(1);
    ..
        Runnable r = () -> {
            try {
                testConnections();
            } catch (InterruptedException | ExecutionException | TimeoutException e) {
                // HANDLE IT
            }
        };
        scheduler.scheduleAtFixedRate(r, secondsInBetweenPolls, secondsInBetweenPolls, TimeUnit.SECONDS);
        }
    ..
private void testConnections() throws InterruptedException, ExecutionException, TimeoutException {
    for (URL u : urls) {
        if (isRunning){
            try{
                CompletableFuture.supplyAsync(() -> testConnection(u)).acceptEither(timeoutAfter(millisConnectionTimeOut, TimeUnit.MILLISECONDS), result -> currentStatus = result).get();
            } catch (Exception e) {
                if (e instanceof TimeoutException) {
                    currentStatus = Result.INTERNET_UNREACHABLE;
                }
            }
            if (currentStatus.equals(Result.INTERNET_REACHED)) {
                break; // first actual internet hit is enough, right?
            }
         }
     }
     notifyListener();
     lastStatus = currentStatus;
}

private void notifyListener() {
    if (lastStatus == null || !currentStatus.equals(lastStatus)) {
        if (currentStatus.equals(Result.INTERNET_REACHED)) {
            listener.connectionIsUp();
        } else {
            listener.connectionIsDown();
        }
    }
}

private Result testConnection(URL url) {
    if (isRunning) {
        HttpURLConnection urlConnect = null;
        try {
            urlConnect = (HttpURLConnection) url.openConnection();
            urlConnect.setConnectTimeout(millisConnectionTimeOut);
            int resultCode = urlConnect.getResponseCode();
            if (resultCode == 200) {
               return Result.INTERNET_REACHED;
            }
         } catch (IOException ignore) {}
     } finally {
             if (urlConnect != null) {
                 urlConnect.disconnect();
             }
         }
    }
    return Result.INTERNET_UNREACHABLE;
}

如果向while循环线程添加延迟,会发生什么情况。sleep1000;应该没事吧?有一种可能性是,它试图打印太多,并且在打印前几分钟的数据时被卡住。一旦您连接,您打印消息,您的套接字实例就会超出范围。你的程序完成了,它没有等着你。你能解释一下为什么这能解决这个问题吗?问题的最初原因是什么?毫不延迟,程序打印数据的速度可能太快,无法反映代码的意图。它工作得很好。然而,当将此应用于GUI Swing时,如果我断开与internet的连接并运行该程序,就会得到未知的hostException。我真的不知道如何捕捉这个异常。我试过:}捕获未知的后异常e,但Eclipse用红色强调它…什么是timeoutAfter?它指示这个CompleteableFuture将超时的时间;这是一个被接受的结果…这并不明显,但在我的例子中,它形成了一个完整的未来。您可以随时使用CompletableFuture来使用超时的任何内容为什么不能在注释中添加多行代码。。。无论如何,如果您愿意,您可以获取我尝试过的完整示例。isRunning属性的用途是什么?我将这些东西连接到我放在周围的一些托盘图标代码中,这样就有一个主gui线程运行并管理tester线程;gui将自己注册为一个监听器——当我拔出插头时,它会翻转图标,当互联网恢复时,它会翻转回来,等等。布尔值和关闭挂钩只是告诉测试线程停止执行,并确保它会死掉。所以最初没有包括主要的方法。第82行应该有一个testConnections;也