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

I don't want to tell the hard way that the internet is unavailable when I catch an exception from url.openStream().
Is there a simple way to tell if the computer is connected to the internet in Java?
In this scenario, "connected to the internet" means being able to download data from a specific url.
If I try to download from it and it is not available, then the program hangs for a bit. I dont want that hanging. Therefore, i need a fast way of querying whether the website is available or not.

The problem you are trying to avoid is waiting for for your http connection to determine that the URL you are trying to access is really unavailable. In order to achieve this you need to stop using url.openStream() which is a shortcut for openConnection().getInputStream() and get some finer control over your connection.
URLConnection conn = url.openConnection();
conn.setConnectTimeout(timeoutMs);
conn.setReadTimeout(timeoutMs);
in = conn.getInputStream();
This code will allow you to timeout the connection attempt if either the connection or the read exceeds the time you provide in the timeoutMs paramater.

Use
Process p1 = java.lang.Runtime.getRuntime().exec("ping www.google.com");
System.out.println(p1.waitFor());
// return code for p1 will be 0 if internet is connected, else it will be 1

There is no such thing as "Internet availability".
Imagine that your HTTP request go through a transparent HTTP proxy, you are trying to access a blacklisted site and you get a HTTP response from the proxy server telling you about access denied. Is Internet available in this scenario or not?
I think you shall be more specific about your problem.

You might be able to tell if a compouter is connected to a network but even if it is there's no guarantee the networking is working or that it's connected to the internet.
This is one of those "suck it and see" problems.
What's wrong with trying to connect? And why are you concerned whether or not they're connected to the internet?

If the criteria is whether you can access a given web server the only way to find out, is to access that web server.
You can, however, do it in a background thread at start up so the application is not delayed by it. Then the "yes/no" answer is available when the actual downloading is desired. Put a message in the status line so the user knows what is going on and is not suprised about uninitiated "connect to network" if s/he is not connected when your program is started.

I don't know much about the low level HTTP plumbing available in Java, but you could always issue an http HEAD request for the url in advance. This causes the server to send back only the headers and not the data. With a 1-3 second timeout, you should be able to avoid any lengthy delays.

If you program is hanging while waiting to download then you are probably using the GUI thread to do the download. If you use a background thread, your program won't hang even if it take a long time to timeout/download.

You could send an ICMP message to a very well known host...

You can check for a NTP server if your firewall does not forbids.
Any way I think the best option is to try to open an URL as you try to avoid, because is the service most commonly to be opened.
You can check for one or two dynamic URL that change constantly. For instace, some web that shows time. For instance this one i found googleing. More than one because the sites can be down ;-)

Related

How to stop UnknownHostException in android

Let me tell you a bit about my app, when the app is in the background, I send some session data to my session_endpoint first, and if sending is failed, I get the exception that the host is unknown from try/catch and send it to same host, which is for sending exceptions exception_endpoint.
So my question is, how is it possible that I can send data to my exception_endpoint and cannot send to session_endpoint, is it about resolving domain ? sending methods are the same by the way. I lose my precious session data. How can I overcome this issue ?
I get java.net.UnknownHostException: Unable to resolve host.
There are several options how you can handle that exception. The simplest way is to cache the requests and fire them on the next app start.
You could also use the alarm manager to try it later or maybe even better use the JobScheduler, there you can define that you require network connectivity. If you need to support older platforms try the nice lib Android-Job. There you can define for much more platforms the scheduling.

Android 3g connection delay

I'll appreciate your help with the following:
Question:
I'm looking to rush the 3g connection and make it connect immediately.
Explanation:
I built an app (for Android), using HttpClient for connecting to my server, and Amazon's AWS API to connect to various Amazon services.
I noticed that occasionally, the connection establishment in 3g takes a lot of time, and it actually seems that Android just waits a while before sending the GET/POST/whatever request, and not even trying until then.
Few Clarifications:
the 3g connection IS working (good signal) and the problem is with 3g ONLY.
when trying to connect to the internet using a browser (e.g Boat Browser), the connection seems to "wake up" and those green&orange arrows at the status bar start lighting again. And..the browser works. Sometimes my request get "awakened" then as well.
My requests DO work, but usually it takes a while (at least 1 minute) until they actually initiate.
I can put some code if needed, but it looks like it isn't related to what I do, it's just how Android works (maybe it's waiting for many requests before initiating 3g connection?), and that some apps (like Boat Browser) force the connection to send their request, or just refresh the 3g connection maybe.
Thank you so much
Ok I found enough information to clear this up!
The best thing to do with AsyncTasks as connection threads is to avoid them apparently,
And use Google Volley instead.
Please look at this link to understand the nuances concerning AsyncTasks:
http://www.jayway.com/2012/11/28/is-androids-asynctask-executing-tasks-serially-or-concurrently/
(I found this link in a separate question but I can't find it, sorry).
And look at this link to understand what is Google Volley and how it's easier to implement a multi-threaded connection with it:
https://developers.google.com/events/io/sessions/325304728
So..To answer the question:
1. On some/most cases, your AsyncTasks will NOT run concurrently.
2. In order to "force" a multi-threaded connection, use Volley (can be configured to run serially btw) or read the link above concerning AsyncTask to "enable" it.

making several request to a server with java without getting banned?

I don't if the question title fits, but here is my problem:
I have a regular webhosting service in hostmonster, with a website built in php.
So I have php script running in a cron job that monitors a xml file for changes, and everytime a new entry comes into that xml file the script stores it in a database.
In the other hand there is java built desktop client, which needs to be noticed ASAP that a new entry is created, for this the client connects to a second php file every second, and this second files tells if there has been changes or not.
The thing is, every 260 connections my I.P gets banned from the server :( and the client crashes, the client will be used by several users.
I contacted support on how to handle this, but they tell me to use a single connection, I tried reusing the UrlConnection but after the first request it just gives null. then I tried with Sockets but no luck. I know there are libraries that manage this but I dont know how are they called. Can someone give me advice?
thank you guys.
Use a long polling method. Hold the connection opened until response arrives. This way you only need to ask for the update once.
PHP may not be the best tool for this job though.

SocketTimeoutException occurring non-stop after app has run for a while, but are instantly-solved by restarting it

I have a crawler Java application which is supposed to connect to some HTTP servers, download the HTML content of their pages, then move on to other HTTP servers. For this task, I've used the Apache HTTP library.
At the first few hours of the run, things seem to work rather smoothly (there are some connection-related exceptions thrown around from time to time, but that's to be expected).
Yet after a while, it seems like I keep getting SocketTimeoutException on every request I send out. The exception does not occur on the HttpClient class's "execute" method, but rather when I try to get the content of the Entity (which I retrieve from the HttpResponse object), or when I try to write that content to a file.
Then, if I stop the application, and start it over again, things seem to go back to working fine - even though it picks up from where it stopped at, meaning it's interacting with the same servers which I received the SocketTimeoutException when trying to interact with before.
I tried looking for all kinds of possible clean-ups that I might be missing and might be essential when using this library, but couldn't find anything.
Any help would be greatly appreciated.
Thanks.
This sounds like the kind of thing which could be caused by connection pools where you're not closing things when you're done with them, if the timeout occurs while the client library waits to retrieve a pooled connection. Are you sure you're closing everything properly (in finally statements)?
If you run Wireshark to monitor your traffic, what network traffic occurs while it's "broken"?
Make sure that you're not using a lot of http requests at the same time. For example, send 5 http requests, and wait for first response. Then you can make another request etc. Looks like your http requests opens too much sockets.

Ping vs HTTP HEAD

I'm writing a Java app which has a feature to check whether it's connected to the internet by periodically trying to access a server. My first idea was to Ping the server - but turned out to be complicated to achieve in Java. So I remade it to send HTTP HEAD requests and check for the HTTP response code instead. I have two questions:
1) Are HTTP HEAD requests "as reliable" as pings? Ping would be my first natural choice to check if something is available. Maybe just because it's so easy to run on the command line.
2) If I send HTTP HEAD requests to a third-party website to check if it is accessible, is there some standard frequency at which these should be sent? Eg if I send them every second, would that be discouraged or even get me blocked from those services?
An HTTP HEAD is generally more reliable than a ping, as ICMP connections are often blocked and HTTP is usually open. Checking for a connectivity every second sounds pretty excessive, but it really depends on your use case what third party site you are trying to "ping".
I can't comment on whether its more effective to use HEAD or trying to do something like drop to the system and do a ping; but I don't think either of them is the solution you should be doing. IMHO, it isn't necessary to poll your connection. There are a lot of situations where a connection could be dropped and I don't think polling will provide much in the way of mitigating the problem. Also, the user might be annoyed. I know that if I were using an application, and then started doing something else, and all of a sudden I got a "connection lost to 3rd party error" from an application I wasn't even paying attention to; I would be very annoyed.
If your application depends on a connection being present, then I think its fair to handle this with exception handlers. I'm willing to be bet that whatever API you're using throws some kind of exception whenever you attempt a network action and you aren't able to establish a connection. So, what I would do is in whatever class you're initializing the network action, I would follow this paradigm:
try {
performNetworkAction();
} catch (NoConnectionFoundException e) {
// handle the situation here
}
Your application shouldn't be able to determine when a connection was lost, just how to react when you attempt a network action and no connection is found.
That being said - you still may disagree with me. If that is the case then the frequency of polling allowed/recommended might be documented in the API for the service you're using. Also, if the resource from the 3rd party is static, you should cache it as opposed to getting it over and over again.
I wanted to expand #Dave's answer, and a comment would not suffice.
When you lose internet connectivity, a java.io.IOException is thrown. Look at the sub-classes of IOException - UnknownHostException, SocketException and ProtocolException are the ones that usually smell of "No Internet Connection"
Create a central place for handling exceptions (this is good practice in itself). If you get any of the IOException's I mentioned above, set isInternetAvailable to false.
Instead of polling for internet connection, switch to retrying the operation you want to perform. You achieve the same thing
Use a backoff strategy - exponential backoff works great. For example, after it fails the first time, you wait for 5s. After the second failure, you wait for 25s and so on. Gmail webapp uses this strategy. Twitter commons has utility classes for backoff.

Categories