如何通过Java检查是否可以连接到互联网?一种方法是:
final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
... if we got here, we should have net ...
但是有没有更适合执行这项任务的东西,特别是如果您需要经常进行连续检查,而且失去互联网连接的可能性非常高?
如何通过Java检查是否可以连接到互联网?一种方法是:
final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
... if we got here, we should have net ...
但是有没有更适合执行这项任务的东西,特别是如果您需要经常进行连续检查,而且失去互联网连接的可能性非常高?
你应该连接到你实际应用程序需要的地方,否则就是在测试你是否与某个不相关的地方(比如这里的 Google)建立了连接。
特别是,如果你正在尝试与一个 Web 服务交互,并且如果你控制着这个 Web 服务,那么最好有一些廉价的“获取状态”的 Web 方法。这样你就可以更好地知道你的“真实”调用是否有可能成功。
在其他情况下,仅仅打开应该开放的端口或发送一个 ping 可能就足够了。在这里,InetAddress.isReachable
API 可能是一个合适的选择。
你提供的基本代码再加上调用 connect
应该就足够了。所以,可能只是 Google 不可用,但需要联系的其他网站却可用,但这种情况有多大可能呢?此外,该代码应该仅在实际无法访问外部资源时执行(在 catch
块中尝试查明失败的原因),因此我认为,如果你感兴趣的外部资源和 Google 都不可用,那么很可能是网络连接问题。
private static boolean netIsAvailable() {
try {
final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
conn.connect();
conn.getInputStream().close();
return true;
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
return false;
}
}
人们建议使用INetAddress.isReachable。问题在于,一些网站会配置其防火墙以阻止ICMP Ping消息。因此,“ping”可能会失败,即使Web服务是可访问的。
当然,反过来也是如此。虽然Web服务器已关闭,但主机可能仍会响应ping。
当然,由于本地防火墙限制,计算机可能无法直接连接到某些(或所有)Web服务器。
根本问题在于,“能否连接到互联网”是一个含糊不清的问题,这种情况很难进行测试,而不需要:
因此,通常最简单的解决方案是让应用程序尝试访问它需要访问的任何内容,并借助人类智慧进行诊断。
try-with-resources
语句时,我们不需要关闭资源。import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class InternetAvailabilityChecker
{
public static boolean isInternetAvailable() throws IOException
{
return isHostAvailable("google.com") || isHostAvailable("amazon.com")
|| isHostAvailable("facebook.com")|| isHostAvailable("apple.com");
}
private static boolean isHostAvailable(String hostName) throws IOException
{
try(Socket socket = new Socket())
{
int port = 80;
InetSocketAddress socketAddress = new InetSocketAddress(hostName, port);
socket.connect(socketAddress, 3000);
return true;
}
catch(UnknownHostException unknownHost)
{
return false;
}
}
}
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface interf = interfaces.nextElement();
if (interf.isUp() && !interf.isLoopback())
return true;
}
我自己还没有尝试过。
这段代码:
"127.0.0.1".equals(InetAddress.getLocalHost().getHostAddress().toString());
true
,否则返回false
(我不确定这对所有计算机都适用)。
这种方法比其他方法快得多。
编辑:我发现只有在“翻转开关”(笔记本电脑上)或其他系统定义选项关闭互联网连接时,它才能正常工作。即,系统本身知道不要寻找任何IP地址。
InetAddress.isReachable
有时会在存在Internet连接时返回false。
Java中检查互联网可用性的替代方法是: 此函数执行实际的ICMP ECHO
ping。
public static boolean isReachableByPing(String host) {
try{
String cmd = "";
if(System.getProperty("os.name").startsWith("Windows")) {
// For Windows
cmd = "ping -n 1 " + host;
} else {
// For Linux and OSX
cmd = "ping -c 1 " + host;
}
Process myProcess = Runtime.getRuntime().exec(cmd);
myProcess.waitFor();
if(myProcess.exitValue() == 0) {
return true;
} else {
return false;
}
} catch( Exception e ) {
e.printStackTrace();
return false;
}
}
使用NetworkInterface等待网络的代码对我来说是有效的,直到我从固定网络地址切换到DHCP。稍加改进后,它也可以与DHCP一起工作:
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface interf = interfaces.nextElement();
if (interf.isUp() && !interf.isLoopback()) {
List<InterfaceAddress> adrs = interf.getInterfaceAddresses();
for (Iterator<InterfaceAddress> iter = adrs.iterator(); iter.hasNext();) {
InterfaceAddress adr = iter.next();
InetAddress inadr = adr.getAddress();
if (inadr instanceof Inet4Address) return true;
}
}
}
这适用于在openSuse 13.1上使用Java 7进行IPv4网络连接。原始代码的问题是,尽管从挂起状态恢复后接口已经启动,但IPv4网络地址尚未分配。等待地址分配后,程序可以连接服务器。但我不知道在IPv6的情况下该怎么办。
URL url=new URL("http://[any domain]");
URLConnection con=url.openConnection();
/*now errors WILL arise here, i hav tried myself and it always shows "connected" so we'll open an InputStream on the connection, this way we know for sure that we're connected to d internet */
/* Get input stream */
con.getInputStream();
我通常将它分为三个步骤。
如果在任何一个步骤失败,我会向用户提供相应的错误消息。