InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
当我可以ping通IP时,为什么isReachable
返回false
?
InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
当我可以ping通IP时,为什么isReachable
返回false
?
//also, this fails for an invalid address, like "www.sjdosgoogle.com1234sd"
InetAddress[] addresses = InetAddress.getAllByName("www.google.com");
for (InetAddress address : addresses) {
if (address.isReachable(10000))
{
System.out.println("Connected "+ address);
}
else
{
System.out.println("Failed "+address);
}
}
//output:*Failed www.google.com/74.125.227.114*
// in case of Linux change the 'n' to 'c'
Process p1 = java.lang.Runtime.getRuntime().exec("ping -n 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
Ping的-c选项将使ping尝试一次连接服务器(与我们在终端上使用的无限ping相反)。
如果主机可达,将返回0。否则,将返回"2"。
这样做更简单,但当然它是特定于平台的。 使用此命令可能会有某些特权限制,但我发现它在我的机器上有效。
isReachable
我得到了失败的结果,使用 ping 我得到了 icmp 不允许的错误信息。你知道现在该怎么处理吗? - Yuvipublic boolean waitFor(long timeout, TimeUnit unit)
在java.lang.Process中(@since 1.8)。 - indivisibleisReachable
更加可靠。 - Lii我来这里是为了得到对于同样问题的答案,但我对所有的答案都不满意,因为我正在寻找一种跨平台的解决方案。这里是我编写的代码,它是跨平台的,但需要关于其他计算机上任何开放端口的信息(我们大多数时候都有这些信息)。
private static boolean isReachable(String addr, int openPort, int timeOutMillis) {
// Any Open port on other machine
// openPort = 22 - ssh, 80 or 443 - webserver, 25 - mailserver etc.
try {
try (Socket soc = new Socket()) {
soc.connect(new InetSocketAddress(addr, openPort), timeOutMillis);
}
return true;
} catch (IOException ex) {
return false;
}
}
更新:根据最近在此答案下的评论,这是以上代码的简明版本:
private static boolean isReachable(String addr, int openPort, int timeOutMillis) {
// Any Open port on other machine
// openPort = 22 - ssh, 80 or 443 - webserver, 25 - mailserver etc.
try (Socket soc = new Socket()) {
soc.connect(new InetSocketAddress(addr, openPort), timeOutMillis);
return true;
} catch (IOException ex) {
return false;
}
}
InetAddress.isReachable()
已经通过端口 7 做的完全相同,只是后者更加智能化地处理各种可能的 IOExceptions
对可达性的含义。 - user207421try
块就足够了,对吧?只需将 "withResources" 部分移动到外部的 try
块中并删除内部的块即可。 - tomorrow如果你只想检查互联网连接是否正常,请使用以下方法。该方法将返回true,以表示互联网已连接。最好使用程序尝试连接的站点地址。
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 (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
我不确定在2012年提出问题时的情况。
现在,ping将作为root执行。通过ping可执行文件的授权,您将看到+s标志,并且属于root的进程,这意味着它将以root身份运行。在ping所在位置运行ls -liat,您应该会看到它。
因此,如果您以root身份运行InetAddress.getByName(“www.google.com”)。isReacheable(5000),它应该返回true。
您需要适当的授权来使用原始套接字,ICMP(ping使用的协议)使用原始套接字。
InetAddress.getByName与ping一样可靠,但是您需要在进程上拥有适当的权限才能使其正常运行。
其他答案没有明确提到,因此我特别提一下。在Unix系统中,isReachable()的ping部分需要root权限访问。正如bestsss在4779367中指出的那样:
如果你问为什么从bash运行ping不需要,实际上也是需要的。执行ls -l /bin/ping即可。
由于在我的情况下使用root权限不是一个选项,所以解决方案是允许防火墙访问特定服务器的端口7。
InetAddress.isReachable
是 flappy 的,有时会返回无法访问的地址,但我们可以 ping。
我尝试了以下操作:
ping -c 1 <fqdn>
并检查 exit status
。
对于我尝试过并且 InetAddress.isReachable
不起作用的所有情况都有效。
既然您可以ping通计算机,那么您的Java进程应该具有足够的特权来执行检查。可能是由于使用了较低范围的端口。如果您使用sudo/superuser运行Java程序,我敢打赌它会起作用。
因为isReachable使用的是TCP协议(通过WireShark),而Ping命令使用的是ICMP协议,如果你想返回true,你需要打开7号端口。
检查互联网
public boolean isInternetAvailable() {
try {
InetAddress ipAddr = InetAddress.getByName("google.com");
//You can replace it with your name
return !ipAddr.equals("");
} catch (Exception e1) {
try {
Process p1 = java.lang.Runtime.getRuntime().exec("/system/bin/ping -W 1 -c 1 www.google.com");
int returnVal = 0;
returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
return reachable;
} catch (Exception e2) {
e2.printStackTrace();
return false;
}
}
}
检查网络连接
private boolean isNetworkConnected() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
}