如何在Java中检查互联网连接是否存在?
如何检查是否可以通过java连接到互联网?一种方法是:
final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
... if we got here, we should have net ...
但是是否有更合适的方法来执行该任务,特别是如果您需要经常连续检查并且很可能会失去互联网连接?
How do you check if you can connect to the internet via java? One way would be:
final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
... if we got here, we should have net ...
But is there something more appropriate to perform that task, especially if you need to do consecutive checks very often and a loss of internet connection is highly probable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
您应该连接到您的实际应用程序需要的地方。否则,您将测试是否与不相关的地方(本例中为 Google)有连接。
特别是,如果您尝试与 Web 服务通信,并且您控制着该 Web 服务,那么采用某种廉价的“获取状态”Web 方法将是一个好主意。这样您就可以更好地了解您的“真实”通话是否有效。
在其他情况下,只需打开与应打开的端口的连接就足够了 - 或者发送 ping。
InetAddress.isReachable
很可能是满足您需求的合适 API。
You should connect to the place that your actual application needs. Otherwise you're testing whether you have a connection to somewhere irrelevant (Google in this case).
In particular, if you're trying to talk to a web service, and if you're in control of the web service, it would be a good idea to have some sort of cheap "get the status" web method. That way you have a much better idea of whether your "real" call is likely to work.
In other cases, just opening a connection to a port that should be open may be enough - or sending a ping.
InetAddress.isReachable
may well be an appropriate API for your needs here.您基本上提供的代码加上对
connect
的调用就足够了。是的,可能只是 Google 不可用,但您需要联系的其他网站却可以访问,但这种可能性有多大?另外,此代码应该仅在您实际上无法访问外部资源时执行(在catch
块中尝试找出失败的原因),所以我想说,如果您的感兴趣的外部资源和 Google 不可用,您可能遇到网络连接问题。The code you basically provided, plus a call to
connect
should be sufficient. So yeah, it could be that just Google's not available but some other site you need to contact is on but how likely is that? Also, this code should only execute when you actually fail to access your external resource (in acatch
block to try and figure out what the cause of the failure was) so I'd say that if both your external resource of interest and Google are not available chances are you have a net connectivity problem.人们建议使用 INetAddress.isReachable。问题在于某些站点将其防火墙配置为阻止 ICMP Ping 消息。因此,即使 Web 服务可以访问,“ping”也可能会失败。
当然,反之亦然。即使网络服务器已关闭,主机也可能会响应 ping。
当然,由于本地防火墙的限制,计算机可能无法直接连接到某些(或所有)Web 服务器。
根本问题是“可以连接到互联网”是一个定义不明确的问题,如果没有
因此,一般来说,最简单的解决方案是应用程序尝试访问它需要访问的任何内容,然后依靠人类智能来进行诊断。
People have suggested using INetAddress.isReachable. The problem is that some sites configure their firewalls to block ICMP Ping messages. So a "ping" might fail even though the web service is accessible.
And of course, the reverse is true as well. A host may respond to a ping even though the webserver is down.
And of course, a machine may be unable to connect directly to certain (or all) web servers due to local firewall restrictions.
The fundamental problem is that "can connect to the internet" is an ill-defined question, and this kind of thing is difficult to test without:
So generally, the simplest solution is for an app to just try to access whatever it needs to access, and fall back on human intelligence to do the diagnosis.
这段代码应该可靠地完成这项工作。
请注意,使用
try-with-resources
时声明我们不需要关闭资源。This code should do the job reliably.
Note that when using the
try-with-resources
statement we don't need to close the resources.如果您使用的是 java 6,可以使用 NetworkInterface 检查可用的网络接口。
即是这样的:
我自己还没有尝试过。
If you're on java 6 can use NetworkInterface to check for available network interfaces.
I.e. something like this:
Haven't tried it myself, yet.
此代码:
如果离线,则返回 - 给我 -
true
,否则返回false
。 (嗯,我不知道这是否适用于所有计算机)。这比上面的其他方法要快得多。
编辑:我发现只有当用于互联网连接的“翻转开关”(在笔记本电脑上)或其他一些系统定义的选项关闭时,这才有效。也就是说,系统本身知道不寻找任何 IP 地址。
This code:
Returns - to me -
true
if offline, andfalse
, otherwise. (well, I don't know if this true to all computers).This works much faster than the other approaches, up here.
EDIT: I found this only working, if the "flip switch" (on a laptop), or some other system-defined option, for the internet connection, is off. That's, the system itself knows not to look for any IP addresses.
如果存在互联网连接,
InetAddress.isReachable
有时会返回 false。在 java 中检查互联网可用性的另一种方法是:此函数进行真正的
ICMP ECHO
ping。InetAddress.isReachable
sometime return false if internet connection exist.An alternative method to check internet availability in java is : This function make a real
ICMP ECHO
ping.我通常将其分为三个步骤。
如果在任何时候失败,我都会向用户提供适当的错误消息。
I usually break it down into three steps.
If it fails at any point, I provide the appropriate error message to the user.
将上述语句放在 try catch 块中,如果 catch 中出现异常,则表示没有建立互联网连接。 :-)
Put the above statements in try catch blocks and if an exception in caught means that there's no internet connection established. :-)
使用 NetworkInterface 等待网络的代码对我有用,直到我从固定网络地址切换到 DHCP。一个轻微的增强使其还可以与 DHCP 一起使用:
这适用于 openSuse 13.1 中的 Java 7 for IPv4 网络。原始代码的问题在于,虽然接口从挂起恢复后已启动,但尚未分配 IPv4 网络地址。等待分配后,程序可以连接到服务器。但我不知道在 IPv6 的情况下该怎么办。
The code using NetworkInterface to wait for the network worked for me until I switched from fixed network address to DHCP. A slight enhancement makes it work also with DHCP:
This works for Java 7 in openSuse 13.1 for IPv4 network. The problem with the original code is that although the interface was up after resuming from suspend, an IPv4 network address was not yet assigned. After waiting for this assignment, the program can connect to servers. But I have no idea what to do in case of IPv6.
1) 找出您的应用程序需要连接到的位置。
2) 设置工作进程来检查 InetAddress.isReachable 监视到该地址的连接。
1) Figure out where your application needs to be connecting to.
2) Set up a worker process to check InetAddress.isReachable to monitor the connection to that address.
此代码包含在我用来测试连接是否可用的 jUnit 测试类中。我总是收到连接,但如果您检查内容长度,如果未知,它应该为 -1:
This code is contained within a jUnit test class I use to test if a connection is available. I always receive a connection, but if you check the content length it should be -1 if not known :
(现在)有用于此目的的 API,但它们是特定于平台的:
在 Android
ConnectivityManager
(https://developer.android.com/training/basics/network-ops/reading-network-state) 可以完成您需要的一切。在 Windows 上 INetworkListManager:: GetConnectivity(为此您需要 JNI)
在通用 Linux 上,您可能需要测试是否可以访问 DNS 服务器和 Google,如上所述。
Apple 也可能有一种方法可以做到这一点
(我会使用可用的特定工具)
There are (nowadays) APIs for this, but they are platform specific:
On Android
ConnectivityManager
(https://developer.android.com/training/basics/network-ops/reading-network-state) does everything you need.On Windows INetworkListManager::GetConnectivity (for which you'll need a JNI)
On generic Linux, you are probably stuck with testing if you have access to a DNS server and Google, as above.
there is probably an Apple way to do this as well
(I'd use the specific tools where available)
你可以简单地这样写
You can simply write like this
这对我来说效果很好。
This have worked well for me.
还有一个 gradle 选项
--offline
这可能会导致您想要的行为。There is also a gradle option
--offline
which maybe results in the behavior you want.下面的代码可以让我们获取Android设备上的网络状态
The following piece of code allows us to get the status of the network on our Android device