I'm having a weird behavior with the isReachable
method of InetAddress
class.
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...).
- When using timeout < 1500, the method waits 1000ms maximum...
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 :
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 ? (like 1500 in my doubt, but I doubt, huge timeout...)
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. I will assume you work on 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).
What we saw in the
isReachable
method implementation is:NET_Wait
functionSo 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.The
NET_Wait
function is defined here: src/windows/native/java/net/net_util_md.cIt consist in an infinite loop which break when these events occurs during the
select
function call:NET_WAIT_CONNECT
on the socket file descriptor (socket is connected to the remote host)The
select
function is documented in a man page you may consult here. 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.
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.