HttpURLConnection setConnectTimeout() has no effect

I’m connecting to a simple RSS feed using HTTPUrlConnection. It works perfectly. I’d like to add a timeout to the connection since I don’t want my app hanging in the event of a bad connection or whatever. This is the code I use and the setConnectTimeout method doesn’t have any effect whatsoever.

        HttpURLConnection http = (HttpURLConnection) mURL.openConnection();
        http.setConnectTimeout(15000); //timeout after 15 seconds
...

If it helps I’m developing on android.

Enquirer: Jon Snow

||

Solution #1:

You should try to set the read timeout as well (http.setReadTimeout()). Oftentimes, a web server will happily accept your connection, but it might be slow in actually responding to the request.

Respondent: pap

Solution #2:

You probably either/both:
1) Don’t read anything from connection
2) Don’t catch & handle the exception properly

As mentioned here, use logic similar to this:

int TIMEOUT_VALUE = 1000;
try {
    URL testUrl = new URL("http://google.com");
    StringBuilder answer = new StringBuilder(100000);

    long start = System.nanoTime();

    URLConnection testConnection = testUrl.openConnection();
    testConnection.setConnectTimeout(TIMEOUT_VALUE);
    testConnection.setReadTimeout(TIMEOUT_VALUE);
    BufferedReader in = new BufferedReader(new InputStreamReader(testConnection.getInputStream()));
    String inputLine;

    while ((inputLine = in.readLine()) != null) {
        answer.append(inputLine);
        answer.append("
");
    }
    in.close();

    long elapsed = System.nanoTime() - start;
    System.out.println("Elapsed (ms): " + elapsed / 1000000);
    System.out.println("Answer:");
    System.out.println(answer);
} catch (SocketTimeoutException e) {
    System.out.println("More than " + TIMEOUT_VALUE + " elapsed.");
}
Respondent: Caner

Solution #3:

I had a similar problem – because the HttpUrlConnection won’t time out mid-download. For example, if you turn off wifi when download is going, mine continued to say it is downloading, stuck at the same percentage.

I found a solution, using a TimerTask, connected to a AsyncTask named DownloaderTask. Try:

class Timeout extends TimerTask {
    private DownloaderTask _task;

    public Timeout(DownloaderTask task) {
        _task = task;
    }

    @Override
    public void run() {
        Log.w(TAG,"Timed out while downloading.");
        _task.cancel(false);
    }
};

Then in the actual download loop set a timer for timeout-error:

                    _outFile.createNewFile();
                    FileOutputStream file = new FileOutputStream(_outFile);
                    out = new BufferedOutputStream(file);
                    byte[] data = new byte[1024];
                    int count;
                    _timer = new Timer();
                    // Read in chunks, much more efficient than byte by byte, lower cpu usage.
                    while((count = in.read(data, 0, 1024)) != -1 && !isCancelled()) { 
                        out.write(data,0,count);
                        downloaded+=count;
                        publishProgress((int) ((downloaded/ (float)contentLength)*100));
                        _timer.cancel();
                        _timer = new Timer();
                        _timer.schedule(new Timeout(this), 1000*20);
                    }
                    _timer.cancel();
                    out.flush();

If it times out, and won’t download even 1K in 20 seconds, it cancels instead of appearing to be forever downloading.

Respondent: NoBugs

Solution #4:

I was facing the same issue. Setting the connectionTimeout and readTimeout does not seems to return the exception as expected, but take really. It took me while to check the URLConnection() Method and understand what is going on. In the documentation for setConnectTimeout there is a warning

“if the hostname resolves to multiple IP addresses, this client will try each. If connecting to each of these addresses fails, multiple timeouts will elapse before the connect attempt throws an exception.”
This mean s if you have 10 ips resolved by your host your actual time out will “10*readTimeoutSet”.

You can check ips for the the host name here

Respondent: Sojan P R

Solution #5:

http.setConnectTimeout(15000);
http.setReadTimeout(15000);
Respondent: Jack Sun

Solution #6:

It’s caused by:

1. You are connected to wifi but you dont have internet connection.

2. You are connected to GSM data but your transfer is very poor.

In both cases you get a host exception after about 20seconds. In my opinion the best way to get correct is:

public boolean isOnline() {
        final int TIMEOUT_MILLS = 3000;
        final boolean[] online = {false};
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnected()) {
            final long time = System.currentTimeMillis();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        URL url = new URL("http://www.google.com");
                        HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
                        urlc.setConnectTimeout(TIMEOUT_MILLS);
                        urlc.setReadTimeout(TIMEOUT_MILLS);
                        urlc.connect();
                        if (urlc.getResponseCode() == 200) {
                            online[0] = true;
                        }
                    } catch (IOException e) {
                        loger.add(Loger.ERROR, e.toString());
                    }
                }
            }).start();

            while (((System.currentTimeMillis() - time) <= TIMEOUT_MILLS)) {
                if ((System.currentTimeMillis() - time) >= TIMEOUT_MILLS) {
                    return online[0];
                }
            }
        }
        return online[0];
    }

remember – use it in asynctask or service.

Its simple solution, you are starting new Thread with HttpUrlConnection (remember use start() not run()). Than in while loop you are waiting 3 sec for result. If nothing happend return false. This way let you avoid waiting for host exception and avoid problem with not working setConnectTimeout() when you dont have internet connection.

Respondent: Pawe?

Solution #7:

A zero value means infinit time out, which means connection must occure and normally zero is default:

connection.setConnectTimeout(0);
connection.setReadTimeout(0);

refer to here

Respondent: Atef Farouk

Solution #8:

Try to set the ConnectionTimeout before openning the connection.

Respondent: Ovidiu Latcu

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Leave a Reply

Your email address will not be published.