InetAddress isReachable方法是否有最小超时?

时间:2017-09-07 14:56:59

标签: java inetaddress

我对isReachable类的InetAddress方法有一种奇怪的行为。

Method prototype是:

public boolean isReachable(int timeout)
  • 使用超时>时1500(ms),该方法等待确切的时间 作为参数给出(如果目标IP当然不可达......)。
  • 使用超时< 1500 ,该方法最多等待1000毫秒......

代码非常简单:

    InetAddress addr = null;
    String ip = "10.48.2.169";

    try {
        addr = InetAddress.getByName(ip);
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Timestamp s = new Timestamp(System.currentTimeMillis());
    System.out.println(s + "\t Starting tests :");

    pingTest(addr, 100);
    pingTest(addr, 500);
    pingTest(addr, 1000);
    pingTest(addr, 1500);
    pingTest(addr, 2000);
    pingTest(addr, 2500);

pingTest定义于:

public static void pingTest(InetAddress addr, int timeout) {
        boolean result = false;
        try {
            result = addr.isReachable(timeout);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Timestamp s = new Timestamp(System.currentTimeMillis());
        System.out.println(s + "\t (" + timeout + ") " + addr.toString() + " " + result);
    }

然后输出是:

2017-09-07 16:45:41.573  Starting tests :
2017-09-07 16:45:42.542  (100) /10.48.2.169 false
2017-09-07 16:45:43.542  (500) /10.48.2.169 false
2017-09-07 16:45:44.541  (1000) /10.48.2.169 false
2017-09-07 16:45:46.041  (1500) /10.48.2.169 false
2017-09-07 16:45:48.041  (2000) /10.48.2.169 false
2017-09-07 16:45:50.541  (2500) /10.48.2.169 false

所以问题是: InetAddress isReachable方法是否有最小超时?(我怀疑是1500,但我怀疑,超时......)

或许我犯了一个很大的错误,我仍然想念......

告诉我这是不是很清楚。

感谢您的帮助和想法。

1 个答案:

答案 0 :(得分:4)

首先,您应该注意到Java支持的每个平台上INetAddress.isReachable的行为都不相同。我假设您在Windows上工作。

当未记录的行为发生时,您应始终查看源是否可用。对于OpenJDK,Windows的java.net实现是here(它应该与Oracle JVM非常相似,但我不确定这一点。)

我们在isReachable方法实现中看到的是:

  1. 他们不依赖ping,因为他们发现Windows ICMP协议实现太不可靠了
  2. 他们将超时值传递给NET_Wait函数
  3. 所以 isReachable方法不会执行ping ,我们需要检查NET_Wait对超时的处理方式,以了解为什么不到1秒的超时时间为&#39可能。

    此处定义了NET_Wait函数:src/windows/native/java/net/net_util_md.c

    它包含一个无限循环,在select函数调用期间发生这些事件时会中断:

    • NET_WAIT_CONNECT关于套接字文件描述符(套接字连接到远程主机)
    • 超时结束

    select功能记录在您可以咨询的手册页here中。该手册页告诉我们,超时可以被四舍五入到系统时钟粒度,并且内核调度延迟意味着阻塞间隔可能会超出一小部分"。

    这就是为什么不能保证最小超时值。此外,我认为文档没有说明任何最小超时值,因为实现在JVM支持的操作系统上有所不同。

    希望这可以帮助您理解原因。

    但是,要实现所需的超时,您可以在单独的任务中测试可达性。您等到任务返回结果,或者等待超过超时时取消任务或忽略其结果。