Java InetAddress.getByName(host).isReachable(timeout) 的最佳替代方案
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18321118/
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
best Alternative for InetAddress.getByName(host).isReachable(timeout)
提问by
I am trying to reach a host and have the following code
我正在尝试联系主机并拥有以下代码
if(!InetAddress.getByName(host).isReachable(TIMEOUT)){
throw new Exception("Host does not exist::"+ hostname);
}
The hostname I am able to ping from windows, and also did a tracert on it and it returns all the packets. But java throws out exception "Host does not exist::";
我能够从 Windows ping 的主机名,并且还对它进行了跟踪并返回所有数据包。但是java抛出异常“主机不存在::”;
The Timeout value I experimented from giving 2000ms, to 5000ms. I tried 3000 as well. What is the cause of this problem I am not able to understand. I researched on the net and some say that InetAddress.getByName(host).isReachable(time) is not reliable and behaves according to the internal system.
我试验的超时值从 2000 毫秒到 5000 毫秒。我也试过3000。我无法理解这个问题的原因是什么。我在网上研究过,有人说 InetAddress.getByName(host).isReachable(time) 不可靠并且根据内部系统运行。
What is the best alternative for this if this is true. Please suggest.
如果这是真的,最好的选择是什么。请建议。
回答by Shloim
Either open a TCP Socket to a port you think is open (22 for Linux, 139 for Windows, etc.)
打开一个 TCP Socket 到您认为打开的端口(Linux 为 22,Windows 为 139 等)
public static boolean isReachableByTcp(String host, int port, int timeout) {
try {
Socket socket = new Socket();
SocketAddress socketAddress = new InetSocketAddress(host, port);
socket.connect(socketAddress, timeout);
socket.close();
return true;
} catch (IOException e) {
return false;
}
}
Or use some hack to send an actual ping. (inspired from here: http://www.inprose.com/en/content/icmp-ping-in-java)
或者使用一些 hack 发送实际的 ping。(灵感来自这里:http: //www.inprose.com/en/content/icmp-ping-in-java)
public static boolean isReachableByPing(String host) {
try{
String cmd = "";
if(System.getProperty("os.name").startsWith("Windows"))
cmd = "cmd /C ping -n 1 " + host + " | find \"TTL\"";
else
cmd = "ping -c 1 " + host;
Process myProcess = Runtime.getRuntime().exec(cmd);
myProcess.waitFor();
return myProcess.exitValue() == 0;
} catch( Exception e ) {
e.printStackTrace();
return false;
}
}
Same hack for Android can be found here:
可以在此处找到适用于 Android 的相同 hack :
回答by Huon Imberger
I've found that ping -n 1 hostnameisn't reliable either. If you get Reply from X.X.X.X: Destination host unreachable.the command actually gives an exit code of 0, thus giving you a lot of false positives.
我发现这ping -n 1 hostname也不可靠。如果您收到Reply from X.X.X.X: Destination host unreachable.该命令,实际上给出的退出代码为 0,因此会给您带来很多误报。
The solution is to search for the string "TTL" in the result, as it only exists when you get a successful ping. Because the command has a pipe, you also need to use cmd /C.
解决方案是在结果中搜索字符串“TTL”,因为它仅在您获得成功 ping 时才存在。因为命令有一个管道,所以你还需要使用cmd /C.
Here is an example (Windows):
这是一个示例(Windows):
public boolean isReachable(String hostname) throws IOException, InterruptedException {
Process p = Runtime.getRuntime().exec(
"cmd /C ping -n 1 "+hostname+" | find \"TTL\""
);
return (p.waitFor() == 0);
}
I'm not sure of the unix equivalent, and don't have a unix machine to test on.
我不确定 unix 的等价物,也没有要测试的 unix 机器。
回答by Zero
For Android developers: the above method does not work if inetis unavailable (more precisely when DNS cache runs in a timeout); what I found: DSN lookup always takes about 1 minute.
对于 Android 开发者:如果inet不可用,上述方法不起作用(更准确地说,当 DNS 缓存超时运行时);我发现:DSN 查找总是需要大约 1 分钟。
My code is like the following:
我的代码如下所示:
TIMEOUT = 5000;
socket.connect(new InetSocketAddress(ServerDomainName, Port), TIMEOUT);
It is expected that connectthrows a timeout exception within about 5 seconds, but the time was 65 seconds when inetwas unreachable (somebody describes it as fake inetconnection: Connectivity says connected, but inetis unreachable).
预计connect会在大约 5 秒内引发超时异常,但inet无法访问时的时间为 65 秒(有人将其描述为假inet连接:连接说已连接,但inet无法访问)。

