【问题标题】:Detect internet Connection using Java [duplicate]使用Java检测互联网连接[重复]
【发布时间】:2009-07-16 18:48:37
【问题描述】:

可能重复:
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;
        }

【问题讨论】:

    标签: java internet-connection


    【解决方案1】:

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

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

    另一种方法是每隔一段时间实际打开一个对某个网络地址的 HTTP 请求。

    【讨论】:

    • 感谢您的评论。获得反馈和不同的想法总是好的。我想到了 URL 连接,或者为此使用 HttpURLConnection。我不知道这仅测试了 DNS,但我可能不得不接受这种方法。
    • 查看上面的最终代码块并更新说明。
    【解决方案2】:

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

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

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

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

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

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

    【讨论】:

    • 这是一个需要考虑的非常重要的事实。在虚拟机中测试应用程序时,我不得不面对这个问题。并花了很长时间才建立联系。在这种情况下,连接超时至关重要。
    • 考虑添加超时,这在某个时候可能很重要。
    【解决方案3】:

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

    【讨论】:

    • 好点。我认为这就是为什么这个应用程序的 .NET 版本使用操作系统的 DLL。通过这种方式,操作系统可以立即知道是否存在连接,而不是 ping 网站或检查流。这将提出何时划线的问题。一个站点之后?二?正是我想要输入的原因。
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

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

      另外,请记住在尝试联系之前询问用户。

      【讨论】:

      • 唯一可以确定的方法是执行 real 请求。当真实请求成功时,虚拟请求或真实请求可能会失败,或者反之亦然。你无法预测未来。
      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

        这个问题没有真正的意义。没有“连接到互联网”这样的东西。你必须尝试创建一个。所指的 Windows API 仅告诉您调制解调器是否已拨入,而且我已经看到它实际上 cause 拨入,这并不是真正的想法。并不是说我在过去 8 年左右的时间里一直在拨入。

        【讨论】:

        • 这没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。
        • @IanLim 这里给出的答案是“你必须尝试创建一个”,这与大多数其他人的观点一致。
        猜你喜欢
        • 1970-01-01
        • 2012-01-17
        • 2014-02-18
        • 2017-11-30
        • 2012-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多