使用Java检测互联网连接

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

我想看看是否有人在使用Java时有一个简单的方法来检测是否有互联网连接。 目前的应用程序使用WinInit DLL中的“InternetGetConnectedState”方法的窗口,但我的应用程序需要跨平台的Mac操作,这种方式将无法正常工作。 我根本不知道JNI要么在Java中使用DLL,而且它变得令人沮丧。

只有我能想到的方式是打开一个网站的URL连接,如果失败,返回false。 我的另一种方式是在下面,但我不知道这是否一般稳定。 如果我拔掉网线,当尝试创buildInetAddress时,会出现UnknownHostException。 否则,如果电缆连接,我得到一个有效的InetAddress对象。 我没有在Mac上testing下面的代码。

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

更新:最终的代码块在底部。 我决定采取HTTP请求(在这种情况下谷歌)的build议。 它很简单,并向网站发送请求返回数据。 如果我无法从连接中获得任何内容,则不存在互联网。

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

这是解决问题的完全合理的方法。 不好的一面是,你真的在​​testingDNS,而不是testing整个networking,但是在实践中你经常可以把这些看作是等价的。

另外要记住的是,你将需要设置一个系统属性来closures在Java运行时的DNScaching。 否则,可能会继续根据caching的数据报告networking已启动(即使它已closures)。

另一种方法是每隔一段时间实际打开一个HTTP请求到这样的networking地址。

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

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

出于这个原因,我build议你做closuresUI线程,并添加urlConnect.setConnectTimeout(1000); 调用urlConnect.getContent(); 之前 urlConnect.getContent();

这样你就知道这个地址是可以访问的,而且不需要5年的时间来下载一个10K的文件。

(你当然可以改变超时时间来满足你的需求)

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

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

没有testing过这个,但是我build议看一下java.net.NetworkInterface.getNetworkInterfaces()。 这将返回计算机上所有networking接口的枚举,如果没有,则返回null。

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

要达到一定的服务的唯一途径就是对该服务做虚拟的请求。 Ping可能被防火墙阻止。 有些服务器可能可以访问,有些则不可以。 如果您需要与web服务交谈,请为这些请求返回一个静态页面。

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

这个问题并没有真正的意义。 没有像“互联网连接”这样的东西。 你必须尝试创build一个。 所提到的Windows API只会告诉你你的调制解调器是否被拨入,而且我已经看到它实际上会导致拨入,这不是这个想法。 并不是说我在过去8年左右都有过拨号。

第一个解决scheme的一个问题是InetAddress有一个caching,所以,当你失去连接的时候,下一个调用的名字就会通过javacaching来parsing。 随着URL连接aproach你有问题,你使用getContent,应该获取HTML,所以你有数据消费。 如果调用是经常进行的,那么这可能是一个问题(如果您没有运行该软件的设备上的无限数据计划,则更是如此)。

我认为最好的解决办法是做一个到80端口的TCP连接,并在连接成功后closures它。 这将作为最终的代码,但会有更less的stream量。