InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
为什么isReachable
会返回false
?我可以ping IP。
答案 0 :(得分:70)
在许多情况下,“isReachable”方法在我看来并不值得使用。您可以滚动到底部查看我的替代方案,只需测试您是否在线且能够解析外部主机(即google.com)...这通常似乎适用于* NIX机器。
问题
有很多关于此事的喋喋不休:
以下是其他类似问题:
甚至报道了同一件事的错误:
第1部分:问题的可重复示例
请注意,在这种情况下,它会失败。
//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*
第2部分:黑客解决方法
作为替代方案,您可以这样做:
// 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”作为返回值。
更简单 - 但当然它是特定于平台的。 使用此命令可能会有一些特权警告 - 但我发现它可以在我的机器上运行。
请注意: 1)该解决方案不是生产质量。它有点像黑客。如果google关闭,或者您的互联网暂时变慢,或者即使您的权限/系统设置中有一些有趣,也可能返回错误的否定(即即使输入地址可以访问也可能失败)。 2)isReachable失败是一个突出的问题。再次 - 由于JVM尝试访问主机的方式,有几个在线资源表明在撰写本文时没有“完美”的方法 - 我想这是一个本质上特定于平台的任务,尽管很简单,尚未被JVM充分抽象。
答案 1 :(得分:44)
我来这里是为了得到同一个问题的答案,但我对任何答案都不满意,因为我正在寻找一个独立于平台的解决方案。这是我编写的代码,与平台无关,但需要有关其他机器(我们大部分时间都有)的任何开放端口的信息。
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;
}
}
答案 2 :(得分:7)
如果您只想检查它是否连接到互联网,请使用此方法,如果连接了互联网,则返回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;
}
答案 3 :(得分:2)
只是明确地提到它,因为其他答案没有。 isReachable()的ping部分需要在Unix上进行root访问。正如4779367中的优秀人员所指出的那样:
如果你问为什么来自bash的ping没有,实际上它确实也需要。这样做ls -l / bin / ping。
由于在我的情况下使用root不是一个选项,解决方案是允许访问防火墙中的端口7到我感兴趣的特定服务器。
答案 4 :(得分:2)
我不确定在2012年回答原始问题时的状态是什么。
现在,ping将作为root执行。通过ping可执行文件的授权,您将看到+ s标志,以及属于root的进程,这意味着它将以root身份运行。在ping所在的位置运行ls -liat,你应该看到它。
因此,如果您以root身份运行InetAddress.getByName(“www.google.com”)。isReacheable(5000),则应返回true。
你需要对原始套接字进行适当的授权,ICMP使用它(ping使用的协议)
InetAddress.getByName与ping一样可靠,但您需要对该进程拥有适当的权限才能使其正常运行。
答案 5 :(得分:0)
我建议测试互联网连接的唯一可靠方法是实际连接并下载文件,或者通过exec()解析OS ping调用的输出。你不能依赖ping的退出代码,isReachable()就是废话。
如果ping命令正确执行,则不能依赖ping退出代码,因为它返回0。不幸的是,如果ping无法到达目标主机但是从您的家庭ADSL路由器获得“目标主机无法访问”,则ping会正确执行。这是一种被视为成功命中的回复,因此退出代码= 0.必须添加,但这是在Windows系统上。未选中* nixes。
答案 6 :(得分:0)
private boolean isReachable(int nping, int wping, String ipping) throws Exception {
int nReceived = 0;
int nLost = 0;
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("ping -n " + nping + " -w " + wping + " " + ipping);
Scanner scanner = new Scanner(process.getInputStream());
process.waitFor();
ArrayList<String> strings = new ArrayList<>();
String data = "";
//
while (scanner.hasNextLine()) {
String string = scanner.nextLine();
data = data + string + "\n";
strings.add(string);
}
if (data.contains("IP address must be specified.")
|| (data.contains("Ping request could not find host " + ipping + ".")
|| data.contains("Please check the name and try again."))) {
throw new Exception(data);
} else if (nping > strings.size()) {
throw new Exception(data);
}
int index = 2;
for (int i = index; i < nping + index; i++) {
String string = strings.get(i);
if (string.contains("Destination host unreachable.")) {
nLost++;
} else if (string.contains("Request timed out.")) {
nLost++;
} else if (string.contains("bytes") && string.contains("time") && string.contains("TTL")) {
nReceived++;
} else {
}
}
return nReceived > 0;
}
nping是尝试ping ip(数据包)的数量,如果你有繁忙的网络或系统选择biger nping数字。
从ip等待pong的时间,你可以设置它2000ms
使用这种方法你可以这样写:
isReachable(5, 2000, "192.168.7.93");
答案 7 :(得分:0)
或使用这种方式:
public static boolean exists(final String host)
{
try
{
InetAddress.getByName(host);
return true;
}
catch (final UnknownHostException exception)
{
exception.printStackTrace();
// Handler
}
return false;
}
答案 8 :(得分:0)
InetAddress.isReachable
非常脆弱,有时对于我们可以ping的地址返回无法访问的
我尝试了以下操作:
ping -c 1 <fqdn>
并检查exit status
。
适用于我尝试过InetAddress.isReachable
不起作用的所有情况。
答案 9 :(得分:0)
上网查询
$w.onReady(function(){
$w('#button1').disable;
let isChecked = $w("#checkbox1").checked;
let isRequired= $w('#checkbox1').required; // true
$("#checkbox1").click(function(){
$w('#button1').disable;
});
检查网络连接
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;
}
}
}
答案 10 :(得分:0)
因为 isReachable 使用的是 TCP 协议(由 WireShark 提供)Ping 命令使用的是 ICMP 协议,如果要返回 true 需要打开 7 端口
答案 11 :(得分:-1)
由于您可以ping计算机,因此您的Java进程应该以足够的权限运行以执行检查。可能是由于使用较低范围的端口。如果你用sudo / superuser运行你的java程序,我敢打赌它可行。