简体   繁体   English

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

[英]Is there a minimum timeout to InetAddress isReachable method?

I'm having a weird behavior with the isReachable method of InetAddress class. 我在InetAddress类的isReachable方法中有一种奇怪的行为。

Method prototype is : 方法原型是:

public boolean isReachable(int timeout)
  • When using a timeout > 1500 (ms) , the method waits the exact time given as argument (if the target IP is not reachable of course...). 当使用大于1500(ms)超时时 ,该方法将等待作为参数给出的确切时间(如果目标IP当然无法达到...)。
  • When using timeout < 1500 , the method waits 1000ms maximum... 当使用time <1500时 ,该方法最多等待1000ms ...

The code is quite simple : 代码很简单:

    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);

Where pingTest is defined by : 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);
    }

Then the output is : 然后输出是:

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

So the question is : Is there a minimum timeout to InetAddress isReachable method ? 所以问题是: InetAddress isReachable方法是否有最小超时? (like 1500 in my doubt, but I doubt, huge timeout...) (我怀疑是1500,但我怀疑超时时间太长了...)

Or maybe I just made a huge mistake that I still miss... 也许我只是犯了一个我仍然想念的重大错误...

Tell me if this isn't clear enough. 告诉我这是否还不够清楚。

Thanks for your help and thoughts. 感谢您的帮助和想法。

First you should notice that the behavior of INetAddress.isReachable is not the same on each platform supported by Java. 首先,您应该注意到INetAddress.isReachable的行为在Java支持的每个平台上都不相同。 I will assume you work on Windows. 我假设您在Windows上工作。

When undocumented behavior happens you should always look at the source if they are available. 如果发生未记录的行为,则应始终查看源(如果有)。 The java.net implementation for windows is here for the OpenJDK (it should be quite similar for the Oracle JVM, but I am not sure of this). Windows的java.net实现在这里是OpenJDK的实现(对于Oracle JVM,它应该非常相似,但是我不确定)。

What we saw in the isReachable method implementation is: 我们在isReachable方法实现中看到的是:

  1. they don't rely on ping because they find the Windows ICMP protocol implementation too unreliable 他们不依赖ping,因为他们发现Windows ICMP协议实现过于不可靠
  2. they pass the timeout value to the NET_Wait function 他们NET_Wait传递给NET_Wait函数

So the isReachable method doesn't perform a ping and we need to check what the NET_Wait do with the timeout to understand why a less than 1 second timeout isn't possible. 因此,isReachable方法不会执行ping操作 ,我们需要检查NET_Wait如何处理超时,以了解为什么不到1秒的超时是不可能的。

The NET_Wait function is defined here: src/windows/native/java/net/net_util_md.c NET_Wait函数在此处定义: src / windows / native / java / net / net_util_md.c

It consist in an infinite loop which break when these events occurs during the select function call: 它包含一个无限循环,当在select函数调用期间发生以下事件时,该循环会中断:

  • NET_WAIT_CONNECT on the socket file descriptor (socket is connected to the remote host) 套接字文件描述符上的NET_WAIT_CONNECT (套接字已连接到远程主机)
  • The timeout ends 超时结束

The select function is documented in a man page you may consult here . select功能记录在手册页中,您可以在此处进行参考。 This man page tells us that the timeout can "be rounded up to the system clock granularity, and kernel scheduling delays mean that the blocking interval may overrun by a small amount". 该手册页告诉我们超时可以“调整为系统时钟的粒度,并且内核调度延迟意味着阻塞间隔可能会少量溢出”。

This is why there is no guarantee on the minimal timeout value. 这就是为什么不能保证最小超时值的原因。 Also, I think that the documentation doesn't state any minimal timeout value because the implementation differs on OSs supported by the JVM. 另外,我认为该文档没有说明任何最小超时值,因为在JVM支持的操作系统上,实现方式有所不同。

Hope this helps you understanding why. 希望这可以帮助您理解原因。

However, to achieve a wanted timeout you may test the reachability in a separate task. 但是,要实现所需的超时,您可以在单独的任务中测试可达性。 You wait until the task returns the result, or if you wait more than your timeout you cancel the task or ignore its results. 您等待任务返回结果,或者等待时间超过超时,则取消任务或忽略其结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM