我正在尝试访问主机并拥有以下代码
if(!InetAddress.getByName(host).isReachable(TIMEOUT)){
throw new Exception("Host does not exist::"+ hostname);
}
我能够从Windows ping的主机名,并且还对其执行了tracert并返回所有数据包。但java抛出异常“Host is not exists ::”;
我从2000ms到5000ms实验的Timeout值。我也试过3000。我无法理解这个问题的原因是什么。我在网上研究过,有人说InetAddress.getByName(host).isReachable(time)不可靠,并且根据内部系统行事。
如果这是真的,最好的选择是什么。请建议。
答案 0 :(得分:14)
将TCP套接字打开到您认为已打开的端口(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;
}
}
或使用一些黑客发送实际的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;
}
}
可以找到适用于Android的黑客here:
答案 1 :(得分:0)
我发现ping -n 1 hostname
也不可靠。如果你得到Reply from X.X.X.X: Destination host unreachable.
,那么命令实际上会给出退出代码0,从而给你很多误报。
解决方案是搜索字符串" TTL"在结果中,因为它只有在您成功ping时才存在。由于该命令具有管道,因此您还需要使用cmd /C
。
以下是一个示例(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);
}
我不确定unix的等价物,也没有unix机器可供测试。
答案 2 :(得分:0)
对于Android开发人员:如果inet
不可用,则上述方法不起作用(更确切地说,当DNS缓存在超时运行时);我发现:DSN查找总是需要大约1分钟。
我的代码如下:
TIMEOUT = 5000;
socket.connect(new InetSocketAddress(ServerDomainName, Port), TIMEOUT);
预计connect
会在大约5秒内抛出超时异常,但inet
无法访问的时间为65秒(有人将其描述为假inet
连接:连接说已连接,但inet
无法访问)。