可能重复:
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;
}
答案 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连接。这将作为最终的代码,但流量会少得多。