检查互联网连接的可用性 + 2个线程之间通信

发布于 2024-12-01 09:59:58 字数 343 浏览 6 评论 0原文

我有 2 个问题:

  1. 如何检查互联网连接是否打开或关闭?我正在使用 Html Unit,并且在 Windows 上工作。

  2. 我想制作一个 JLabel 来说明我的 JFrame 中互联网连接的可用性。类似于:

while(true)
{
    if(isOnline()) label.setText("online");
    else label.setText("offline");
}

但我认为我需要 2 个分离的线程,但是我如何创建这 2 个线程并在它们之间进行通信并实现这一目标?

I have 2 questions:

  1. How can I check if Internet connection is whether turned on or turned off? I'm using Html Unit and I'm working on Windows.

  2. I want to make a JLabel that states the availability of internet connection in my JFrame. Something like:

while(true)
{
    if(isOnline()) label.setText("online");
    else label.setText("offline");
}

but I think I need 2 sperated threads, but how could I create these 2 threads and communicate between them and achieve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

避讳 2024-12-08 09:59:58

此处回答了类似的问题:how-to-check -if-internet-connection-is-present-in-java

要完成问题的第二部分,我想您可以调用 InetAddress.isReachable 方法在包装在 SwingWorker 线程中的 java.util.Timer 中,以定期轮询连接。

A similar question was answered here: how-to-check-if-internet-connection-is-present-in-java

To do the second part of your question, I suppose you could call the InetAddress.isReachable method in a java.util.Timer that is wrapped in a SwingWorker thread to periodically poll the connection.

傾旎 2024-12-08 09:59:58

while (true) 对您的资源有点苛刻,应该有大约 10 秒的暂停。这并不需要像股票价格行情一样准确和实时。

对于 Swing,规则是不执行任何在事件分派线程上花费时间的操作。后台任务或其他长时间运行的操作不应在其上运行。

对于您的特定情况适用:

由于非 AWT 事件而必须更新其 GUI 的程序:

例如,假设服务器程序可以从可能运行在不同计算机上的其他程序获取请求。这些请求可以随时出现,并且它们会导致在某个可能未知的线程中调用服务器的方法之一。该方法如何更新 GUI?通过在事件调度线程中执行 GUI 更新代码。

因此,我要做的是设置一个计划任务,每 10 秒检查一次互联网连接的可用性关闭事件调度线程 - 这可能最好立即在您的 中设置main 方法。另一方面,GUI 的更新应该发生在事件分派线程上。这是一个可以在标签上进行更新的 Runnable 提案。稍后我将解释ConnectionChecker。我们使用 ExecutorService 执行它并设置 5 秒的超时。如果 ConnectionChecker 在 5 秒内成功,则您已连接,否则未连接。然后,使用 SwingUtilities#invokeLater 使用此结果来更新事件调度线程上的 JLabel

public static class Updater implements Runnable {
    private final JLabel label;
    private final ExecutorService executor;
     /* constructor left out */
    public void run() {
        boolean connected = false;
        Future<?> connHandle = executor.submit(new ConnectionChecker());
        try {
            connHandle.get(5, TimeUnit.SECONDS);
            connected = true;
        } catch (TimeOutException ex) {
            /* connected = false; */
        }
        catch (InterruptedException ex) {
            /* Let it be handled higher elsewhere */
            Thread.currentThread().interrupt();
        } catch (CancellationException ex) {
            /* happens only if you actively cancel the Future */
        } catch (ExecutionException ex) {
            /* connected = false */
        }

        final boolean result = connected;
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                if (result)
                    label.setText("online");
                else
                    label.setText("offline");
            }
        });
    }
}

现在我们必须在 main 方法中设置一个定期执行的 Updater,同时我们还创建 JLabel 和 ExecutorService:

public static void main(String... args) {
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    JLabel label = ...;
    Updater updater = new Updater(label, executor);
    executor.scheduleAtFixedRate(updater, 0, 10, TimeUnit.SECONDS);
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            //GUI initialization code
        }
    });
}

最后,让我们来推理一下 ConnectionChecker。有很多方法可以做到这一点。一个快速而肮脏的解决方案是简单地获取一个可能在未来几年内保留的网页 - 例如 www.google.com 。如果您(正确)连接到 Internet,则此查询将会成功。否则,它最终会抛出一些异常。通过连接,下载应在 5 秒内完成 - 如果不是,则可以安全地使连接尝试超时。无论哪种方式,如果下载未及时成功,您都会在 Updater 中收到异常。使用简单的 URLConnection 或类似的内容进行下载。

while (true) is a bit harsh on your resources, there should be a pause of ~10s in there. It's not like this would need to be as accurate and real-time as a stock price ticker.

With Swing, the rule is to do nothing that takes time on the event dispatch thread. Background tasks or other long-running operations should never run on it.

For your particular case this applies:

Programs whose GUI must be updated as the result of non-AWT events:

For example, suppose a server program can get requests from other programs that might be running on different machines. These requests can come at any time, and they result in one of the server's methods being invoked in some possibly unknown thread. How can that method update the GUI? By executing the GUI update code in the event-dispatching thread.

So what I would do is set up a scheduled task that checks for the availability of an internet connection every 10 seconds off the event-dispatch thread - this is probably best set up right away in your main method. The updating of the GUI on the other hand should then happen on the event dispatch thread. Here is a proposal for a Runnable that could do the update on your label. I'll explain the ConnectionCheckerlater. We execute it using a ExecutorService and set a timeout of 5 seconds. If the ConnectionChecker succeeds within 5 seconds, you are connected, otherwise you are not. This result is then used to update the JLabel on the event dispatch thread using SwingUtilities#invokeLater.

public static class Updater implements Runnable {
    private final JLabel label;
    private final ExecutorService executor;
     /* constructor left out */
    public void run() {
        boolean connected = false;
        Future<?> connHandle = executor.submit(new ConnectionChecker());
        try {
            connHandle.get(5, TimeUnit.SECONDS);
            connected = true;
        } catch (TimeOutException ex) {
            /* connected = false; */
        }
        catch (InterruptedException ex) {
            /* Let it be handled higher elsewhere */
            Thread.currentThread().interrupt();
        } catch (CancellationException ex) {
            /* happens only if you actively cancel the Future */
        } catch (ExecutionException ex) {
            /* connected = false */
        }

        final boolean result = connected;
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                if (result)
                    label.setText("online");
                else
                    label.setText("offline");
            }
        });
    }
}

Now we have to set up a periodically executed Updater in the main method, where we also create the JLabel and the ExecutorService:

public static void main(String... args) {
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    JLabel label = ...;
    Updater updater = new Updater(label, executor);
    executor.scheduleAtFixedRate(updater, 0, 10, TimeUnit.SECONDS);
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            //GUI initialization code
        }
    });
}

Finally, let's reason about ConnectionChecker. There's plenty of ways how you could do this. A quick and dirty solution is to simply fetch a web page that's likely to stay in the next few years - how about www.google.com. If you are connected to the Internet (correctly), this query will succeed. Otherwise, it will finally throw some Exception. With a connection, the download should be done in under 5 seconds - if it's not, then it's safe to time out the connection attempt. Either way, you will receive an Exception in your Updater if the download did not succeed in time. Use a simple URLConnection or similar for the download.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文