How to check if I have an internet connection (InetAddress.isReachable)?

edited February 2014 in Android Mode

So I'm working on a program that relies on pulling data from the internet. I'm trying to use InetAddress but without much luck.

Here's what I have:

    import java.util.*;
    import java.net.InetAddress;

String address = "www.google.com";
int timeOut = 5000;
boolean connected;
InetAddress inet;

void setup()
{

try
{

 inet = InetAddress.getByName("www.google.com");
 //println(inet);
 connected = inet.isReachable(timeOut);
 if(connected == true)
 {
 println("can connect");
//then we'll do something fun here
 }
 else
 {
  println("can't connect");
//no fun until you have an internet connection. prompt to retry.
 }
}
catch (Exception e)
{
 e.printStackTrace();
}

}

void draw()
{

}

The interesting thing is that I'm not getting a catch error and if i uncomment println(inet) it prints out:

www.google.com/74.125.194.99 not www.google.com

What's with the ip numbers at the end anyway?

If i change www.google.com to http://www.google.com, it throws errors.

I even tried www.processing.org with the same lack of luck (println(inet) yields www.processing.org/205.186.154.181)

If i change inet = InetAddress.getByName("www.google.com"); to inet = InetAddress.getByName("www.google.com/74.125.194.99); I get errors.

Same with www.processing.org to www.processing.org/205.186.154.181 or http://www.processing.org/205.186.154.181

I've been scouring the internet on how InetAdress works to try to resolve this myself, but haven't had any luck.

Any help would be great.

Thanks! Shields

Answers

  • Answer ✓

    Is this actually an Android question? It doesn't look like it - but if the problem is indeed Android specific, then you most likely have a permissions problem: you must enable the INTERNET permission. If this is not an Android-related question, then it should not be in the Android category...

    I'm certainly not an expert in networking (as my lack of technical jargon will demonstrate), but I believe that I understand what is going on. I was unable to connect to google.com, although I was able to connect to processing.org.

    Firstly, when you print the InetAddress object, it outputs the host name and the host address, separated by a slash. This isn't a problem. To illustrate this, try this piece of code instead:

    println(inet.getHostName()); //Prints the host name: "google.com"
    println(inet.getHostAddress()); //Prints the host addres: "173.194.43.40"
    

    I'm pretty certain that in this scenario, the Google servers are mucking up the situation. I'll get to that a bit later. Instead, let's look at the processing.org example, which does work (for me, at least...). This is the output I receive for processing.org:

    processing.org
    205.186.154.181
    can connect
    

    That's relatively straightforward. The connection is successful. Also, if we try to connect with the IP address (205.186.154.181) (as opposed to the domain name), it will work as expected (why is this necessary? Hold on a second...):

    processing.org
    205.186.154.181
    can connect
    

    Now, here's the tricky part - the Google servers. As expected, connecting to google.com is unsuccessful:

    google.com
    74.125.226.14
    can't connect
    

    Now, let's try with the IP address above (74.125.226.14):

    lga15s42-in-f14.1e100.net
    74.125.226.14
    can't connect
    

    Wait, what? That's not google.com any more! You may also have noticed that my google.com IP address is different from your google.com IP address. Also, if you ran the same test as I did in the last step, you would likely have a different host name.

    This is because we are connecting to different Google servers based on our geographic locations. Google, being a large ("large" doesn't really do it justice) internet company, has many servers for different parts of the world. As such, the main server (google.com) automatically redirects the user to the nearest local server.

    Somewhere along the way, InetAddress is getting tripped up by this redirect. There may be a more advanced APIs available, especially for a task as simple as testing to see if the website is available.

    Other big websites, such as microsoft.com, apple.com, and stackoverflow.com seem to have local server redirects as well (unsurprisingly). Of course, there are many smaller websites that do not employ this redirection technology, such as slashdot.org, that can be connected to in this manner.

    Conclusion: Hopefully I've explained the problem sufficiently (and accurately)... and although I don't have a proper solution (at the moment), you should be on the right track to understanding what's going on.

  • edited February 2014

    I appreciate the response. I suppose technically, this question could extend to Processing in general. I put it here, because the program I'm working on is an Android one. Maybe I should move it to help a larger audience of Processing users that might have this issue.

    That's a good point about the Google servers being accessed based on geography. So I'll stick with the Processing.org address for now. Actually, the best would be to get my butt in gear and set up my own, which will ultimately hold the information I'll be accessing anyway. Up until that point, I've used my computer as a local MySQL and Php server when I've done programs in the past (or I've used Twitter- which is a damn handy tool).

    Back on topic.

    I'm going to go back and study what you've written along side of my code and see if I can't get a positive response from InetAddress. I'll switch back to Java mode and try to get it to work. Then migrate back to Android mode.

    In the interim, I was trying to figure this out on my own and tried using URL and URLConnection. I had some luck there. But is there any benefit of one over the other?

    My intial thought is while I could connect to a site (or my site) using URL at setup(), what happens if the network drops while the program is running. I'd like to be able to ping (isReachable) the site before sending/retrieving data, to make sure that it can be done and if not return an error message to the user.

    Thoughts on either approach?

    For reference, here's my code on using URL:

    import java.net.*;
    import java.util.*;
    
     boolean connectivity;
    
     void setup()
     {
    
       try
       {
         URL url = new URL("http://processing.org");
         URLConnection conn = url.openConnection();
         conn.setConnectTimeout(5000);
         conn.connect();
         connectivity = true;
         println("can connect / " + connectivity);
       }
       catch (Exception e)
       {
         connectivity = false;
         System.out.println("can't connect / " + connectivity);
       }
     }//end setup()
    
Sign In or Register to comment.