72

How do you check if you can connect to the internet via java? One way would be:

final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
... if we got here, we should have net ...

But is there something more appropriate to perform that task, especially if you need to do consecutive checks very often and a loss of internet connection is highly probable?

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
Chris
  • 15,429
  • 19
  • 72
  • 74
  • The answer to this is the same as to mamy other questions of the same form. The only proper way to determine whether any resource is available is to try to use it, in the normal course of execution, and cope with failure as and when it happens. Any other technique is one form or another of trying to predict the future. – user207421 Dec 04 '14 at 20:54

18 Answers18

56

You should connect to the place that your actual application needs. Otherwise you're testing whether you have a connection to somewhere irrelevant (Google in this case).

In particular, if you're trying to talk to a web service, and if you're in control of the web service, it would be a good idea to have some sort of cheap "get the status" web method. That way you have a much better idea of whether your "real" call is likely to work.

In other cases, just opening a connection to a port that should be open may be enough - or sending a ping. InetAddress.isReachable may well be an appropriate API for your needs here.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 3
    The link to isReachable went to the wrong class. It's at http://java.sun.com/javase/6/docs/api/java/net/InetAddress.html#isReachable – Chris Mazzola Sep 09 '09 at 23:21
  • 19
    what if you connect to a resource you want to communicate with and it fails. how do you know that it was the problem of the target server and not bcs there was no internet connection? so 'connect to the place that your actual application needs' is not really a solution that would not be a reliable check – Chris Sep 10 '09 at 00:39
  • 4
    @Chris: It depends whether you really care what the problem is. I agree that you can get more diagnostic information if (after a failure) you then connect somewhere else as well. But the most important piece of information is surely "Can I use the resource I'm trying to use?" – Jon Skeet Sep 10 '09 at 05:20
  • @JonSkeet However instead of "Can I use the resource I'm trying to use?", sometimes we do need to answer the question "Is my Internet up?" (for example, an app that logs internet connectivity). – Pacerier Jan 18 '12 at 07:00
  • @Pacerier: In that case, I'd expect to try to connect to a number of different resources, ideally with a number of different protocols. It's not like "Is my internet up?" is always a binary decision - perhaps your web proxy is down, but your mail server is still accepting traffic, for example. – Jon Skeet Jan 18 '12 at 07:08
  • @JonSkeet So do you mean to say if I turn off my router and/or un-plugged my network cable (so I could no longer have *fresh* data), the only way to determine that had happened is to connect to a number of different resources and examine the connections? – Pacerier Jan 18 '12 at 07:18
  • 2
    @Pacerier: There are lots of different things that could go wrong, and diagnosing *where* there's a problem is a tricky matter. What if you hadn't done anything, but your ISP's pipe to the rest of the world had gone down? Then you might still have a perfectly valid router connection etc - and you might even be able to get to your ISP's domain - but wouldn't be able to reach other sites. All I'm saying is that "Is my internet up?" doesn't make sense as a question, really - not in precise terms. What are *you* proposing the test should be? – Jon Skeet Jan 18 '12 at 07:22
  • @JonSkeet Hmm, I'm not sure exactly, I'm just thinking that its reasonable for a user to want to answer this question "Hey I can't access http://www.facebook.com. Is facebook down or is it me?" So I'm thinking what's a good solution to answer this question. – Pacerier Jan 18 '12 at 07:32
  • 1
    @Pacerier: So you'd try several web sites which are normally up. You'd also want to check whether DNS resolution is working - and indeed whether facebook.com could even be resolved. Then there's the possibility that Facebook is down for a large proportion of users (e.g. traffic for one country is going to one data centre which is having problems) without the site being completely down... – Jon Skeet Jan 18 '12 at 07:35
  • @JonSkeet I have this code in a thread loop performing `isReachable` and my customer has a pfsense balancing over 2 wans... recently I get in trouble my `isReachable` loop was returing "unreachable" but the linux ping was performing OK, after I restart my app the thread comes back to working (returning TRUE on `isReachable`), why? – Beto Neto Feb 23 '21 at 20:19
  • @BetoNeto: I *suspect* there's some caching involved somewhere, but I'm afraid I don't know any more than that. – Jon Skeet Feb 23 '21 at 20:22
  • @JonSkeet yes, I suspect about some "cache" also, but where and why! Now I changing this loop to make a "hard-connect" each 5 seconds via `new Socket().connect(addr, 1000)` and I expect that will solve my problems.. but I realy like to understand why `isReachable` having this behaivor. – Beto Neto Feb 23 '21 at 20:29
28

The code you basically provided, plus a call to connect should be sufficient. So yeah, it could be that just Google's not available but some other site you need to contact is on but how likely is that? Also, this code should only execute when you actually fail to access your external resource (in a catch block to try and figure out what the cause of the failure was) so I'd say that if both your external resource of interest and Google are not available chances are you have a net connectivity problem.

private static boolean netIsAvailable() {
    try {
        final URL url = new URL("http://www.google.com");
        final URLConnection conn = url.openConnection();
        conn.connect();
        conn.getInputStream().close();
        return true;
    } catch (MalformedURLException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        return false;
    }
}
Boris Treukhov
  • 17,493
  • 9
  • 70
  • 91
Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331
  • This works but takes a while till it returns `false`. Any faster solution? `Cmd` immediately tells me that the host couldn't be found when I try to ping it. – BullyWiiPlaza Mar 22 '15 at 21:09
18

People have suggested using INetAddress.isReachable. The problem is that some sites configure their firewalls to block ICMP Ping messages. So a "ping" might fail even though the web service is accessible.

And of course, the reverse is true as well. A host may respond to a ping even though the webserver is down.

And of course, a machine may be unable to connect directly to certain (or all) web servers due to local firewall restrictions.

The fundamental problem is that "can connect to the internet" is an ill-defined question, and this kind of thing is difficult to test without:

  1. information on the user's machine and "local" networking environment, and
  2. information on what the app needs to access.

So generally, the simplest solution is for an app to just try to access whatever it needs to access, and fall back on human intelligence to do the diagnosis.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • well, not ill defined. the question is just "is there internet" nothing more. – Chris Sep 10 '09 at 00:43
  • 5
    That is my point. The question "is there internet" is ill-defined. Read the text above for examples that are intended to illustrate this. – Stephen C Sep 10 '09 at 04:07
  • 1
    @Chris: "Internet" is ill-defined. Being able to get to Google doesn't mean you can necessarily get anywhere else, for example. (Imagine if the DNS server is down, but you happen to have a DNS entry in your hosts file.) – Jon Skeet Sep 10 '09 at 05:22
  • And not being able to get to Google doesn't mean you cannot get to where the user actually wants to go. – Stephen C Sep 10 '09 at 05:33
  • @Stephen C: ok, now i got the point. maybe i have to try another way to accomplish my need. thxn for comments. – Chris Sep 10 '09 at 09:43
9

This code should do the job reliably.

Note that when using the try-with-resources statement we don't need to close the resources.

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class InternetAvailabilityChecker
{
    public static boolean isInternetAvailable() throws IOException
    {
        return isHostAvailable("google.com") || isHostAvailable("amazon.com")
                || isHostAvailable("facebook.com")|| isHostAvailable("apple.com");
    }

    private static boolean isHostAvailable(String hostName) throws IOException
    {
        try(Socket socket = new Socket())
        {
            int port = 80;
            InetSocketAddress socketAddress = new InetSocketAddress(hostName, port);
            socket.connect(socketAddress, 3000);

            return true;
        }
        catch(UnknownHostException unknownHost)
        {
            return false;
        }
    }
}
BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
8

This code:

"127.0.0.1".equals(InetAddress.getLocalHost().getHostAddress().toString());

Returns - to me - true if offline, and false, otherwise. (well, I don't know if this true to all computers).

This works much faster than the other approaches, up here.


EDIT: I found this only working, if the "flip switch" (on a laptop), or some other system-defined option, for the internet connection, is off. That's, the system itself knows not to look for any IP addresses.

Mordechai
  • 15,437
  • 2
  • 41
  • 82
  • not working for "127.0.0.1" but showing reply to other reachable ip address – Harshit Jul 13 '15 at 07:50
  • Works for me and I like it and using it. This is kind of pre-check. A preliminary check to ensure that network interface is connected which you may invoke before checking Internet connection. – kinORnirvana Mar 12 '16 at 16:09
  • This is complete nonsense: InetAddress.getLocalHost().getHostAddress() will give you the local IP address in your network. So e.g. something like 10.0.0.1 or 192.168.0.1. The result has nothing to do with your online/offline status. – Jörg Aug 29 '23 at 21:36
8

If you're on java 6 can use NetworkInterface to check for available network interfaces. I.e. something like this:

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
  NetworkInterface interf = interfaces.nextElement();
  if (interf.isUp() && !interf.isLoopback())
    return true;
}

Haven't tried it myself, yet.

Kutzi
  • 1,295
  • 1
  • 15
  • 19
  • 3
    this only checks that the interface is enabled. It doesn't check internet connection. – siamii Dec 22 '11 at 19:54
  • Nevertheless the network interface being up is a prerequisite for an internet connection. I think this makes sense as the first step of a more robust solution. It allows you to at least see if you have an active network interface without sending any network traffic at all. – adamfisk Oct 27 '12 at 04:09
  • Which is not what the OP asked for. – user207421 Dec 04 '14 at 07:11
  • The OP didn't understand that the question of "is the Internet up" is ill-defined, because the Internet is a LOT of things, any number of which can be up or down causing a wide variety of types of failures. This is one of them, and is potentially useful information for the OP, or other people who check this question. The OP rejected simply connecting to the desired resource. Barring that, this is one step of many to answer the ill-defined original question. – Jeff Learman Aug 10 '18 at 19:53
6

InetAddress.isReachable sometime return false if internet connection exist.

An alternative method to check internet availability in java is : This function make a real ICMP ECHO ping.

public static boolean isReachableByPing(String host) {
     try{
                String cmd = "";
                if(System.getProperty("os.name").startsWith("Windows")) {   
                        // For Windows
                        cmd = "ping -n 1 " + host;
                } else {
                        // For Linux and OSX
                        cmd = "ping -c 1 " + host;
                }

                Process myProcess = Runtime.getRuntime().exec(cmd);
                myProcess.waitFor();

                if(myProcess.exitValue() == 0) {

                        return true;
                } else {

                        return false;
                }

        } catch( Exception e ) {

                e.printStackTrace();
                return false;
        }
}
Flowerking
  • 2,551
  • 1
  • 20
  • 30
Shibina EC
  • 135
  • 2
  • 11
4

The code using NetworkInterface to wait for the network worked for me until I switched from fixed network address to DHCP. A slight enhancement makes it work also with DHCP:

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
    NetworkInterface interf = interfaces.nextElement();
    if (interf.isUp() && !interf.isLoopback()) {
    List<InterfaceAddress> adrs = interf.getInterfaceAddresses();
    for (Iterator<InterfaceAddress> iter = adrs.iterator(); iter.hasNext();) {
        InterfaceAddress adr = iter.next();
        InetAddress inadr = adr.getAddress();
        if (inadr instanceof Inet4Address) return true;
            }
    }
}

This works for Java 7 in openSuse 13.1 for IPv4 network. The problem with the original code is that although the interface was up after resuming from suspend, an IPv4 network address was not yet assigned. After waiting for this assignment, the program can connect to servers. But I have no idea what to do in case of IPv6.

kleopatra
  • 51,061
  • 28
  • 99
  • 211
harald
  • 41
  • 2
4
URL url=new URL("http://[any domain]");
URLConnection con=url.openConnection();

/*now errors WILL arise here, i hav tried myself and it always shows "connected" so we'll open an InputStream on the connection, this way we know for sure that we're connected to d internet */

/* Get input stream */
con.getInputStream();

Put the above statements in try catch blocks and if an exception in caught means that there's no internet connection established. :-)

Rushil
  • 41
  • 1
4

I usually break it down into three steps.

  1. I first see if I can resolve the domain name to an IP address.
  2. I then try to connect via TCP (port 80 and/or 443) and close gracefully.
  3. Finally, I'll issue an HTTP request and check for a 200 response back.

If it fails at any point, I provide the appropriate error message to the user.

Marcus Adams
  • 53,009
  • 9
  • 91
  • 143
  • 2
    I think this may be a good answer but can you elaborate on it, because it's not a good answer right now. – Pacerier Jan 18 '12 at 06:55
3

1) Figure out where your application needs to be connecting to.

2) Set up a worker process to check InetAddress.isReachable to monitor the connection to that address.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
2

This code is contained within a jUnit test class I use to test if a connection is available. I always receive a connection, but if you check the content length it should be -1 if not known :

  try {
    URL url = new URL("http://www.google.com");
    URLConnection connection = url.openConnection();

    if(connection.getContentLength() == -1){
          fail("Failed to verify connection");
    }
  } 
  catch (IOException e) {
      fail("Failed to open a connection");
      e.printStackTrace();
  }
blue-sky
  • 51,962
  • 152
  • 427
  • 752
  • Some servers return -1 for content length (or even omit the header altogether!) even though the webpage loads normally in a browser, as they use alternate content transfer schemes to deliver webpages, and so this answer won't be accurate for all websites. A better way to verify the connection would be to try reading the response data in a new thread (with an optional maximum timeout specified) so that if the server is indeed down, you won't receive any response data, and if it's up but just slow you won't get stuck waiting for the data while your program wants to to something else. – Brian_Entei Jun 04 '23 at 15:20
2
public boolean checkInternetConnection()
{
     boolean status = false;
     Socket sock = new Socket();
     InetSocketAddress address = new InetSocketAddress("www.google.com", 80);

     try
     {
        sock.connect(address, 3000);
        if(sock.isConnected()) status = true;
     }
     catch(Exception e)
     {
         status = false;       
     }
     finally
     {
        try
         {
            sock.close();
         }
         catch(Exception e){}
     }

     return status;
}
Héctor M.
  • 2,302
  • 4
  • 17
  • 35
Zoka
  • 393
  • 3
  • 14
0

You can simply write like this

import java.net.InetAddress;
import java.net.UnknownHostException;

public class Main {

    private static final String HOST = "localhost";

    public static void main(String[] args) throws UnknownHostException {

        boolean isConnected = !HOST.equals(InetAddress.getLocalHost().getHostAddress().toString());

        if (isConnected) System.out.println("Connected");
        else System.out.println("Not connected");

    }
}
Aldo Canepa
  • 1,791
  • 2
  • 16
  • 16
0

There are (nowadays) APIs for this, but they are platform specific:

(I'd use the specific tools where available)

Rich
  • 885
  • 12
  • 15
0

This have worked well for me.

try{  
        InetAddress addr = InetAddress.getByName("google.com" );
        
    }catch(IOException e){
        JOptionPane.showMessageDialog(new JFrame(),"No Internet connection.\nTry again later", "Network Error", JOptionPane.ERROR_MESSAGE);    
    }
OSXMonk
  • 581
  • 6
  • 6
-3

There is also a gradle option --offline which maybe results in the behavior you want.

Dirk Hoffmann
  • 1,444
  • 17
  • 35
-3

The following piece of code allows us to get the status of the network on our Android device

public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            TextView mtv=findViewById(R.id.textv);
            ConnectivityManager connectivityManager=
                  (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if(((Network)connectivityManager.getActiveNetwork())!=null)
                    mtv.setText("true");
                else
                    mtv.setText("fasle");
            }
        }
    }
Hkachhia
  • 4,463
  • 6
  • 41
  • 76
edwin
  • 1
  • 1
  • Welcome to StackOverflow. Please always include a textual description. Also, it looks like you just lifted some code out of context, including code that's not related to the question. The more you make others work to decipher the information hidden in your post, the less you help everyone. Is this for Android only? – Jeff Learman Aug 10 '18 at 20:03