我正在尝试使用Java的isReachable()方法来测量我的电脑和服务器之间的ping延迟。到目前为止,我一直在使用这种方法:
Process p1 = Runtime.getRuntime().exec("ping -n 1 " + indIP);
int pingValue = 0;
long t1 = System.currentTimeMillis();
try {
p1.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long t2 = System.currentTimeMillis();
int exit = p1.exitValue();
if (exit==0){
pingValue = (int) (t2-t1);
return pingValue;
}
else
return -1;
但是我注意到它返回的值高于使用CMD获得的ping值(大约+ 10ms)。
所以我尝试使用InetAddress提供的方法,但值似乎完全错误。
以下是代码:
String servername = "xx.xx.xx.xx";
InetAddress addr = InetAddress.getByName(servername);
long currentTime = System.currentTimeMillis();
boolean pingOK = addr.isReachable(2000);
currentTime = System.currentTimeMillis() - currentTime;
if(pingOK) {
System.out.println("Ping: "+ currentTime+ " ms");
} else {
System.out.println("Ping failed.");
}
例如,如果我尝试通过CMD对服务器执行ping操作,则会获得9-10ms,但此方法会为同一服务器返回100倍的值,或者根本不起作用。我在Stackoverflow上看了一下其他线程,但我找不到任何能让我的ping检查更准确的内容。
提前感谢您的时间。
编辑:通过定义另一种“测量”系统延迟的方法,我得到了更准确的值:
public static int getSysLatency() throws IOException{
long t3 = System.currentTimeMillis();
Process p2 = Runtime.getRuntime().exec("ping -n 1 127.0.0.1");
try {
p2.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t3 = System.currentTimeMillis()-t3;
return (int) t3;
}
这种情况下的延迟应该<1ms,因此在调用Process p1 = Runtime.getRuntime().exec("ping -n 1 " + indIP);
时我可以让系统“延迟”。
然后我将t3减去pingValue,我得到了更好的延迟值,这几乎与通过CMD显示的相同。
答案 0 :(得分:1)
请参阅此Stack Overflow问题:Why does InetAddress.isReachable return false, when I can ping the IP address?和本文:http://bordet.blogspot.com/2006/07/icmp-and-inetaddressisreachable.html。
简而言之,ping
使用ICMP,但isReachable()
通常不会。 Windows不能正确支持ICMP,Linux / Unix支持它但需要root权限。在这两种情况下,isReachable()
回退到在端口7上进行TCP调用,这可能会因为此端口经常关闭而失败。如果它没有失败,它的行为与ping
的行为完全不同,正如您所注意到的那样。
我知道的最佳解决方案是使用ping
通过Runtime.getRuntime().exec()
,就像您的原始代码一样,这是特定于平台但“有效”的。上面的Stack Overflow问题的第一个答案包含有关此解决方案的更多详细信息。