使用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量。