Detect internet Connection using Java [duplicate]

Possible Duplicate:
How to check if internet connection is present in java?

I want to see if anyone has an easy way of detecting if there is an internet connection when using Java. The current app used the "InternetGetConnectedState" method in the WinInit DLL for windows, but my app needs to be cross-platform for mac operation and this way will not work. I do not know JNI at all either to use DLLs in Java and it became frustrating fast.

Only ways I could think of were tring to open a URL connection to a website and if that fails, return false. My other way is below, but I didn't know if this was generally stable. If I unplug my network cable i do get an UnknownHostException when trying to create the InetAddress. Otherwise if the cable is connected I get a valid InetAddress object. I didnt test the below code on a mac yet.

Thanks for any examples or advice you can provide.

UPDATE: Final code block is at the bottom. I decided to take the advice of an HTTP request (in this case Google). Its simple and sends a request to the site for data to be returned. If I cannot get any content from the connection, there is no internet.

public static boolean isInternetReachable()
        {
            try {

                InetAddress address = InetAddress.getByName("java.sun.com");

                if(address == null)
                {
                    return false;
                }

            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            }
            return true;
        }

Final Code Block:

//checks for connection to the internet through dummy request
        public static boolean isInternetReachable()
        {
            try {
                //make a URL to a known source
                URL url = new URL("http://www.google.com");

                //open a connection to that source
                HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();

                //trying to retrieve data from the source. If there
                //is no connection, this line will fail
                Object objData = urlConnect.getContent();

            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            }
            return true;
        }

Solution 1:

That's a perfectly reasonable approach to solving the problem. The bad thing is that you are really testing DNS rather than testing the whole network, but in practice you can often get by with treating those as equivalent.

The other thing to remember, is that you will need to set a system property to turn off dns caching in the java runtime. Otherwise it may continue to report that the network is up based upon cached data (even though it is down).

Another approach would be to actually open an HTTP request to some network address such as this every so often.

Solution 2:

I must add that although the final code block given above is good, it has one flaw - it is possible for it to take a very long time to contact the address specified, but the address is still reachable.

In my instance when testing with one address the method would return true, but take 10 seconds or longer to get a response. In this case the server was reachable, but not for any useful purposes since the connection was so slow. This occurs because the default timeout for HttpURLConnection is 0, or infinite.

For this reason I'd recommend you do the checking off the UI thread, and add urlConnect.setConnectTimeout(1000); before calling urlConnect.getContent();

This way you know the address is reachable, and that it won't take 5 years to download a 10k file.

(You might of course want to change the the timeout time to suit your needs)

Also I'd recommend not checking a generic address (google.com etc) unless your program generally accesses more than a few domains. If you're just accessing one or two then check that domain.

Solution 3:

Note that it could return false if the java.sun.com is not responding! In this case you should check another site to be certain.

Solution 4:

Haven't tested this, but I suggest looking at java.net.NetworkInterface.getNetworkInterfaces(). This returns an Enumeration of all network interfaces on the machine, or null if there are none.

I'm not sure if it's safe to assume that a non-null response ensures a valid network connection -- depending on your needs, you may or may not need to filter out loopback addresses (which I think you could do with java.net.NetworkInterface.getInetAddresses() on each returned NetworkInterface, and then calling InetAddress.isLoopbackAddress() on each one.)