使用Java检测internet连接

使用Java检测internet连接,java,internet-connection,Java,Internet Connection,可能重复: 我想看看是否有人有一个简单的方法来检测是否有互联网连接时,使用Java。当前应用程序在windows的WinInit DLL中使用了“InternetGetConnectedState”方法,但我的应用程序需要跨平台才能进行mac操作,这种方式无法工作。我根本不知道JNI在Java中使用DLL,而且很快就变得令人沮丧 我能想到的唯一方法是尝试打开一个指向网站的URL连接,如果失败,则返回false。我的另一种方法是下面,但我不知道这是否是普遍稳定的。如果我拔下网络电缆,在尝试创建I

可能重复:

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

我能想到的唯一方法是尝试打开一个指向网站的URL连接,如果失败,则返回false。我的另一种方法是下面,但我不知道这是否是普遍稳定的。如果我拔下网络电缆,在尝试创建InetAddress时确实会出现未知的后异常。否则,如果连接电缆,我将获得有效的InetAddress对象。我还没有在mac上测试下面的代码

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

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

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;
        }

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

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


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

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

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


我不确定是否可以安全地假设非空响应可以确保有效的网络连接——根据您的需要,您可能需要也可能不需要过滤掉环回地址(我认为您可以在每个返回的NetworkInterface上使用java.net.NetworkInterface.getInetAddresses(),然后调用InetAddress.isLoopbackAddress()确保您能够访问给定服务的唯一方法是对该服务执行虚拟请求。ping可能被防火墙阻止。某些服务器可能是可访问的,而其他服务器则是不可访问的。如果您需要与Web服务对话,请为这些请求返回一个静态页面


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

这个问题没有真正的意义。没有所谓的“互联网连接”。您必须尝试创建一个。提到的Windows API只告诉您调制解调器是否已拨入,我看到它实际上会导致拨入,但这并不是完全正确的想法。在过去8年左右的时间里,我并没有拨入电话。

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


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

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

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

因此,我建议您检查UI线程,并添加
urlConnect.setConnectTimeout(1000)urlConnect.getContent()之前的代码>

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

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


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

谢谢您的评论。得到反馈和不同的想法总是好的。我想到了URL连接,或者使用HttpURLConnection。我不知道这个只测试了DNS,但我可能不得不接受这个方法。请参阅上面的最后一个代码块和更新说明。很好。我想这就是为什么这个应用的.NET版本在操作系统中使用DLL的原因。通过这种方式,操作系统可以立即知道是否存在连接,而不是ping网站或检查流。它将提出何时划界的问题。一个站点之后?两个?这正是我想要投入的原因。这是一个需要考虑的非常重要的事实。在虚拟机中测试应用程序时,我不得不面对这个问题。花了很长时间才联系上。在这种情况下,连接超时是至关重要的。考虑添加超时可能在某个时候很重要。这不能提供问题的答案。若要评论或要求作者澄清,请在其帖子下方留下评论。@IanLim这里的答案是“y”