使用 Java 检测互联网连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1139547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect internet Connection using Java
提问by
Possible Duplicate:
How to check if internet connection is present in java?
可能的重复:
如何检查 java 中是否存在互联网连接?
I want to see if anyone has an easy way of detecting if there is an internet connection when using Java. The current app used the "InternetGetConnectedState" method in the WinInit DLL for windows, but my app needs to be cross-platform for mac operation and this way will not work. I do not know JNI at all either to use DLLs in Java and it became frustrating fast.
我想看看是否有人在使用 Java 时有一种简单的方法来检测是否有互联网连接。当前的应用程序在Windows的WinInit DLL中使用了“InternetGetConnectedState”方法,但我的应用程序需要跨平台进行mac操作,这种方式不起作用。我根本不知道 JNI 在 Java 中使用 DLL,而且它很快变得令人沮丧。
Only ways I could think of were tring to open a URL connection to a website and if that fails, return false. My other way is below, but I didn't know if this was generally stable. If I unplug my network cable i do get an UnknownHostException when trying to create the InetAddress. Otherwise if the cable is connected I get a valid InetAddress object. I didnt test the below code on a mac yet.
我能想到的唯一方法是尝试打开指向网站的 URL 连接,如果失败,则返回 false。我的另一种方式在下面,但我不知道这是否通常稳定。如果我拔掉网络电缆,我会在尝试创建 InetAddress 时收到 UnknownHostException。否则,如果连接了电缆,我会得到一个有效的 InetAddress 对象。我还没有在 Mac 上测试下面的代码。
Thanks for any examples or advice you can provide.
感谢您提供的任何示例或建议。
UPDATE: Final code block is at the bottom. I decided to take the advice of an HTTP request (in this case Google). Its simple and sends a request to the site for data to be returned. If I cannot get any content from the connection, there is no internet.
更新:最终代码块位于底部。我决定接受 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;
}
Final Code Block:
最终代码块:
//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;
}
采纳答案by jsight
That's a perfectly reasonable approach to solving the problem. The bad thing is that you are really testing DNS rather than testing the whole network, but in practice you can often get by with treating those as equivalent.
这是解决问题的完全合理的方法。不好的是,您实际上是在测试 DNS,而不是测试整个网络,但在实践中,您通常可以将它们视为等效。
The other thing to remember, is that you will need to set a system property to turn off dns caching in the java runtime. Otherwise it may continue to report that the network is up based upon cached data (even though it is down).
要记住的另一件事是,您需要设置一个系统属性来关闭 java 运行时中的 dns 缓存。否则,它可能会根据缓存的数据继续报告网络已启动(即使它已关闭)。
Another approach would be to actually open an HTTP request to some network address such as this every so often.
另一种方法是实际上每隔一段时间就向某个网络地址打开一个 HTTP 请求。
回答by jsight
Note that it could return false if the java.sun.com is not responding! In this case you should check another site to be certain.
请注意,如果 java.sun.com 没有响应,它可能会返回 false!在这种情况下,您应该检查另一个站点以确定。
回答by jptsetme
Haven't tested this, but I suggest looking at java.net.NetworkInterface.getNetworkInterfaces(). This returns an Enumeration of all network interfaces on the machine, or null if there are none.
尚未对此进行测试,但我建议查看 java.net.NetworkInterface.getNetworkInterfaces()。这将返回机器上所有网络接口的枚举,如果没有,则返回 null。
I'm not sure if it's safe to assume that a non-null response ensures a valid network connection -- depending on your needs, you may or may not need to filter out loopback addresses (which I think you could do with java.net.NetworkInterface.getInetAddresses() on each returned NetworkInterface, and then calling InetAddress.isLoopbackAddress() on each one.)
我不确定假设非空响应确保有效的网络连接是否安全 - 根据您的需要,您可能需要也可能不需要过滤掉环回地址(我认为您可以使用 java.net .NetworkInterface.getInetAddresses() 在每个返回的 NetworkInterface 上,然后在每个上调用 InetAddress.isLoopbackAddress()。)
回答by Thorbj?rn Ravn Andersen
The only way to be CERTAIN that you can reach a given service, is to do a dummy request to that service. Pings may be blocked by firewalls. Some server may be reachable, others not. If you need to talk to a webservice, have a static page to return for these requests.
确定您可以访问给定服务的唯一方法是向该服务发出虚拟请求。Ping 可能会被防火墙阻止。有些服务器可能可以访问,有些则不能。如果您需要与 Web 服务对话,请使用静态页面返回这些请求。
Also, remember to ask the user before trying to reach out.
另外,请记住在尝试联系之前询问用户。
回答by user207421
The question doesn't really have a meaning. There is no such thing as a 'connection to the Internet'. You have to try to createone. The Windows API referred to only tells you whether your modem is dialled in or not, and I've seen it actually causedial-ins, which is not exactly the idea. Not that I've had a dial-in for the last 8 years or so.
这个问题真的没有意义。没有“连接到互联网”这样的东西。你必须尝试创造一个。所指的 Windows API 只告诉您您的调制解调器是否已拨入,我已经看到它实际上会导致拨入,这并不完全是这个想法。并不是说我在过去 8 年左右的时间里一直在拨入。
回答by andsegu
A problem with the first solution is that InetAddress has a cache, so, when you lose the connection for the next few invocation the name is resolved via the java cache. With the URL connection aproach you have the problem that you use getContent that should fetch html so there you have data consumption. If the invocations are done very often that could be a problem (more so if you dont have an unlimited data plan on the device running the software).
第一个解决方案的一个问题是 InetAddress 有一个缓存,因此,当您丢失下几次调用的连接时,名称将通过 java 缓存解析。使用 URL 连接方法时,您会遇到问题,即您使用 getContent 应该获取 html,因此您有数据消耗。如果调用非常频繁,这可能是一个问题(如果您在运行该软件的设备上没有无限数据计划,则更是如此)。
I think the best solution would be to do a TCP connection to the 80 port an close it inmediatly after a successfull connection. That would behave as the final code but would have much less traffic.
我认为最好的解决方案是与 80 端口建立 TCP 连接,并在成功连接后立即关闭它。这将表现为最终代码,但流量会少得多。
回答by Joseph Earl
I must add that although the final code block given above is good, it has one flaw - it is possible for it to take a very long time to contact the address specified, but the address is still reachable.
我必须补充一点,虽然上面给出的最终代码块是好的,但它有一个缺陷——它可能需要很长时间才能联系到指定的地址,但该地址仍然可以访问。
In my instance when testing with one address the method would return true, but take 10 seconds or longer to get a response. In this case the server was reachable, but not for any useful purposes since the connection was so slow. This occurs because the default timeout for HttpURLConnection
is 0, or infinite.
在我的实例中,当使用一个地址进行测试时,该方法将返回 true,但需要 10 秒或更长时间才能获得响应。在这种情况下,服务器是可以访问的,但由于连接速度很慢,因此不能用于任何有用的目的。这是因为默认的超时HttpURLConnection
为0,或无限。
For this reason I'd recommend you do the checking off the UI thread, and add urlConnect.setConnectTimeout(1000);
beforecalling urlConnect.getContent();
出于这个原因,我建议您检查 UI 线程,并urlConnect.setConnectTimeout(1000);
在调用之前添加urlConnect.getContent();
This way you know the address is reachable, and that it won't take 5 years to download a 10k file.
这样您就知道该地址是可访问的,并且下载 10k 文件不会花费 5 年的时间。
(You might of course want to change the the timeout time to suit your needs)
(您当然可能希望更改超时时间以满足您的需要)
Also I'd recommend not checking a generic address (google.com etc) unless your program generally accesses more than a few domains. If you're just accessing one or two then check that domain.
此外,我建议不要检查通用地址(google.com 等),除非您的程序通常访问多个域。如果您只是访问一两个,请检查该域。