10

我正在尝试联系主机并拥有以下代码

if(!InetAddress.getByName(host).isReachable(TIMEOUT)){
   throw new Exception("Host does not exist::"+ hostname);
 }

我可以从 Windows ping 的主机名,并且还对其进行了跟踪,它返回了所有数据包。但是java抛出异常“主机不存在::”;

我实验的超时值从 2000 毫秒到 5000 毫秒。我也试过3000。我无法理解这个问题的原因是什么。我在网上进行了研究,有人说 InetAddress.getByName(host).isReachable(time) 不可靠,并且根据内部系统运行。

如果这是真的,那么最好的选择是什么。请建议。

4

3 回答 3

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 的相同 hack :

于 2013-09-17T08:57:06.993 回答
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 机器。

于 2014-10-01T23:55:55.870 回答
0

inet对于Android开发者:如果不可用,上述方法不起作用(更准确地说是DNS缓存运行超时);我发现:DSN 查找总是需要大约 1 分钟。

我的代码如下:

TIMEOUT = 5000;
socket.connect(new InetSocketAddress(ServerDomainName, Port), TIMEOUT); 

预计connect会在大约 5 秒内抛出超时异常,但无法到达的时间是 65 秒inet(有人将其描述为假inet连接:Connectivity 表示已连接,但inet无法访问)。

于 2014-12-03T02:38:12.837 回答