使用Java检测Internet连接

时间:2009-07-16 18:48:37

标签: java internet-connection

  

可能重复:
  How to check if internet connection is present in 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;
        }

7 个答案:

答案 0 :(得分:17)

这是解决问题的完美合理方法。糟糕的是,您确实在测试DNS而不是测试整个网络,但在实践中,您通常可以将这些视为等效。

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

另一种方法是实际上经常打开某个网络地址的HTTP请求。

答案 1 :(得分:11)

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

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

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

这样您就知道地址可以访问,并且下载10k文件不需要5年。

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

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

答案 2 :(得分:3)

请注意,如果java.sun.com没有响应,它可能会返回false!在这种情况下,您应该检查另一个站点是否确定。

答案 3 :(得分:2)

尚未对此进行测试,但我建议查看java.net.NetworkInterface.getNetworkInterfaces()。这将返回计算机上所有网络接口的Enumeration,如果没有,则返回null。

我不确定是否可以安全地假设非空响应确保有效的网络连接 - 根据您的需要,您可能需要也可能不需要过滤掉环回地址(我认为您可以使用每个返回的NetworkInterface上的java.net.NetworkInterface.getInetAddresses(),然后在每个上面调用InetAddress.isLoopbackAddress()。)

答案 4 :(得分:2)

您可以访问给定服务的唯一方法是对该服务进行虚拟请求。 Ping可能被防火墙阻止。某些服务器可以访问,其他服务器则不可访问如果您需要与Web服务进行通信,请为这些请求返回一个静态页面。

此外,请务必在尝试联系之前询问用户。

答案 5 :(得分:2)

这个问题确实没有意义。没有“连接到互联网”这样的东西。您必须尝试创建一个。所引用的Windows API仅告诉您是否拨打了调制解调器,我看到它实际上是导致拨入,这不是主意。并不是说我在过去8年左右都有过拨号。

答案 6 :(得分:2)

第一个解决方案的问题是InetAddress有一个缓存,因此,当您丢失下一次调用的连接时,名称将通过java缓存解析。 使用URL连接方法,您遇到的问题是您使用应该获取html的getContent,因此您有数据消耗。如果调用经常进行可能会出现问题(如果您在运行该软件的设备上没有无限制的数据计划,则更是如此)。

我认为最好的解决方案是在成功连接后立即与80端口建立TCP连接。这将作为最终的代码,但流量会少得多。