Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does InetAddress.isReachable return false, when I can ping the IP address?

InetAddress byName = InetAddress.getByName("173.39.161.140"); System.out.println(byName); System.out.println(byName.isReachable(1000)); 

Why does isReachable return false? I can ping the IP.

like image 628
jiafu Avatar asked Mar 29 '12 09:03

jiafu


People also ask

Can InetAddress be used with I need 6?

An IP address is represented by 32-bit or 128-bit unsigned number. InetAddress can handle both IPv4 and IPv6 addresses.

What is use of InetAddress getByName () function?

The getByName() method of InetAddress class determines the IP address of a host from the given host's name. If the host name is null, then an InetAddress representing an address of the loopback interface is returned.


1 Answers

The "isReachable" method has not been worthy of using for me in many cases. You can scroll to the bottom to see my alternative for simply testing if you're online and capable of resolving external hosts (i.e. google.com) ... Which generally seems to work on *NIX machines.

The issue

There is alot of chatter about this :

  • Here are other, similar questions :

    Detect internet Connection using Java

    How do I test the availability of the internet in Java?

  • And even a reported bug on this same matter :

    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4921816

Part 1 : A reproducible example of the problem

Note that in this case, it fails.

       //also, this fails for an invalid address, like "www.sjdosgoogle.com1234sd"         InetAddress[] addresses = InetAddress.getAllByName("www.google.com");       for (InetAddress address : addresses) {         if (address.isReachable(10000))         {               System.out.println("Connected "+ address);         }         else         {            System.out.println("Failed "+address);         }       }           //output:*Failed www.google.com/74.125.227.114* 

Part 2 : A Hackish Workaround

As an alternative, you can do this :

// in case of Linux change the 'n' to 'c'     Process p1 = java.lang.Runtime.getRuntime().exec("ping -n 1 www.google.com");     int returnVal = p1.waitFor();     boolean reachable = (returnVal==0); 

The -c option of ping will allow ping to simply try to reach the server once(as opposed to the infinite ping which we're used to using at the terminal).

This will return 0 if the host is reachable. Otherwise, you will get "2" as a return value.

Much simpler - but of course it is platform specific. And there may be certain privilege caveats to using this command - but I find it works on my machines.


PLEASE Note that : 1) This solution is not production quality. Its a bit of a hack. If google is down, or your internet is temporarily slow, or maybe even if there is some funniness in your privileges/system settings, if could return false negatives (i.e. it could fail even though the input address is reachable). 2) The isReachable failure is an outstanding issue. Again - there are several online resources indicating that there is no "perfect" way of doing this at the time of this writing, due to the way the JVM tries to reach hosts - I guess it is an intrinsically platform specific task which, although simple, hasn't yet been abstracted sufficiently by the JVM.

like image 78
jayunit100 Avatar answered Oct 06 '22 03:10

jayunit100