使用 Java 检测互联网连接

2022-09-01 06:57:00

可能的重复:
如何检查Java中是否存在互联网连接?

我想看看是否有人在使用Java时有一种简单的方法来检测是否存在互联网连接。当前应用在 Windows 的 WinInit DLL 中使用了“InternetGetConnectedState”方法,但我的应用需要跨平台才能进行 Mac 操作,并且这种方式将不起作用。我根本不知道JNI在Java中使用DLL,它很快就变得令人沮丧。

我能想到的唯一方法是打开一个网站的URL连接,如果失败,则返回false。我的另一种方式在下面,但我不知道这是否总体上是稳定的。如果我拔下我的网络电缆,我在尝试创建InetAddress时会得到一个UnknownHostException。否则,如果电缆已连接,我将得到一个有效的 InetAddress 对象。我还没有在Mac上测试下面的代码。

感谢您提供的任何示例或建议。

更新:最终代码块位于底部。我决定接受HTTP请求的建议(在本例中为Google)。它很简单,并向站点发送请求以返回数据。如果我无法从连接中获取任何内容,则没有互联网。

public static boolean isInternetReachable()
        {
            try {

                InetAddress address = InetAddress.getByName("java.sun.com");

                if(address == null)
                {
                    return false;
                }

            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            }
            return true;
        }

最终代码块:

//checks for connection to the internet through dummy request
        public static boolean isInternetReachable()
        {
            try {
                //make a URL to a known source
                URL url = new URL("http://www.google.com");

                //open a connection to that source
                HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();

                //trying to retrieve data from the source. If there
                //is no connection, this line will fail
                Object objData = urlConnect.getContent();

            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            }
            return true;
        }

答案 1

这是解决问题的完全合理的方法。坏处是,您实际上是在测试DNS而不是测试整个网络,但实际上,您通常可以将它们视为等效网络。

要记住的另一件事是,您需要设置一个系统属性来关闭java运行时中的dns缓存。否则,它可能会根据缓存的数据继续报告网络已启动(即使它已关闭)。

另一种方法是每隔一段时间就向某些网络地址(例如)实际打开HTTP请求。


答案 2

我必须补充一点,尽管上面给出的最终代码块很好,但它有一个缺陷 - 可能需要很长时间才能联系到指定的地址,但地址仍然可以访问。

在我的例子中,当使用一个地址进行测试时,该方法将返回true,但需要10秒或更长时间才能获得响应。在这种情况下,服务器是可访问的,但由于连接速度太慢,因此不能用于任何有用的目的。发生这种情况是因为 的默认超时为 0 或无限。HttpURLConnection

出于这个原因,我建议你检查UI线程,并在调用之前添加urlConnect.setConnectTimeout(1000);urlConnect.getContent();

通过这种方式,您可以知道该地址是可访问的,并且下载10k文件不需要5年。

(当然,您可能希望更改超时时间以满足您的需求)

另外,我建议不要检查通用地址(google.com 等),除非您的程序通常访问多个域。如果您只是访问一个或两个,请检查该域。