337

I have created the following function for checking the connection status:

private void checkConnectionStatus() {
    HttpClient httpClient = new DefaultHttpClient();

    try {
      String url = "http://xxx.xxx.xxx.xxx:8000/GaitLink/"
                   + strSessionString + "/ConnectionStatus";
      Log.d("phobos", "performing get " + url);
      HttpGet method = new HttpGet(new URI(url));
      HttpResponse response = httpClient.execute(method);

      if (response != null) {
        String result = getResponse(response.getEntity());
        ...

When I shut down the server for testing the execution waits a long time at line

HttpResponse response = httpClient.execute(method);

Does anyone know how to set the timeout in order to avoid waiting too long?

Thanks!

Cristian
  • 198,401
  • 62
  • 356
  • 264
Niko Gamulin
  • 66,025
  • 95
  • 221
  • 286

10 Answers10

625

In my example, two timeouts are set. The connection timeout throws java.net.SocketTimeoutException: Socket is not connected and the socket timeout java.net.SocketTimeoutException: The operation timed out.

HttpGet httpGet = new HttpGet(url);
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used. 
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT) 
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpResponse response = httpClient.execute(httpGet);

If you want to set the Parameters of any existing HTTPClient (e.g. DefaultHttpClient or AndroidHttpClient) you can use the function setParams().

httpClient.setParams(httpParameters);
Ashish Kudale
  • 1,230
  • 1
  • 27
  • 51
kuester2000
  • 6,955
  • 2
  • 21
  • 16
  • What if you are using `AndroidHttpClient`? How would you attach the parameters? – Thomas Ahle Dec 13 '10 at 22:49
  • 3
    What will the HttpResponse return if the connection times out? At the moment once my HTTP request is made, I then check the status code upon the call returning, however I get a NullPointerException when checking this code if the call has timed out... basically, how do I handle the situation when the call does timeout? (I'm using very similar code to your answer given) – Tim Feb 27 '11 at 16:45
  • Hi, sorry but I do get "The method setParams(HttpParams) is undefined for the type AndroidHttpClient". – jellyfish Apr 20 '11 at 12:32
  • 10
    @jellyfish - Despite the documentation, AndroidHttpClient does _not_ extend DefaultHttpClient; rather, it implements HttpClient. You'll need to use DefaultHttpClient to have available the setParams(HttpParams) method. – Ted Hopp Jun 10 '11 at 14:58
  • @Ted Hopp: thanks! I found out that setParams() works for HttpRequest, so this is a solution if one wants to use AndroidHttpClient. – jellyfish Jun 14 '11 at 08:19
  • When I insert `httpParameters`, it should show to me this exceptions? Or I just need to catch? because the only exceptions I can see are `ClientProtocolException` and `IOException` – coffee Jul 27 '11 at 16:22
  • Readers must know its default value [see docs](http://developer.android.com/reference/org/apache/http/params/HttpConnectionParams.html) – Vikas Aug 04 '11 at 04:57
  • 3
    Hey guys,t hanks for the excellent answer. But, I would like to show a toast to the users on connection timeout ... any way I can detect when the connection times out? – Arnab Chakraborty Sep 28 '11 at 05:39
  • Hi Guys, I am using HTTPClient and what will be my connection time out if i do not set explicitly. I mean what will be default connection time out..i think it is 15 secs. Am i right or do i need to set explicitly. – Rakesh Gondaliya Dec 02 '11 at 11:54
  • @Aki httpClient.execute() requires you to catch IOException... You can put your Toast message there. – Mark Pazon May 05 '12 at 16:47
  • 2
    Doesn't work. I tested on my Sony and Moto, they all get tucked. – thecr0w Jul 08 '13 at 09:30
  • This scenario does not handle "device is connected to wifi and wifi is not connected to Internet "....not working at all the default time out of HTTP Client is 40 sec and that of AndroidHTTPClient is 20 sec we can not low it down to our desired time – Usman Kurd Oct 09 '13 at 12:57
  • For those saying that this does not work, please be aware that HTTP requests, first try to find the host IP with a DNS request and then makes the actual HTTP request to the server, so you also need to set a timeout for the DNS request. I will post an answer with the full code to do this. – David Darias Jul 26 '15 at 23:09
  • if internet connection is fast is it have to wait for 8 sec – Nouman Shah Nov 11 '16 at 06:39
13

To set settings on the client:

AndroidHttpClient client = AndroidHttpClient.newInstance("Awesome User Agent V/1.0");
HttpConnectionParams.setConnectionTimeout(client.getParams(), 3000);
HttpConnectionParams.setSoTimeout(client.getParams(), 5000);

I've used this successfully on JellyBean, but should also work for older platforms ....

HTH

8

If your are using Jakarta's http client library then you can do something like:

        HttpClient client = new HttpClient();
        client.getParams().setParameter(HttpClientParams.CONNECTION_MANAGER_TIMEOUT, new Long(5000));
        client.getParams().setParameter(HttpClientParams.SO_TIMEOUT, new Integer(5000));
        GetMethod method = new GetMethod("http://www.yoururl.com");
        method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, new Integer(5000));
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
        int statuscode = client.executeMethod(method);
Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
7

If you're using the default http client, here's how to do it using the default http params:

HttpClient client = new DefaultHttpClient();
HttpParams params = client.getParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);
HttpConnectionParams.setSoTimeout(params, 3000);

Original credit goes to http://www.jayway.com/2009/03/17/configuring-timeout-with-apache-httpclient-40/

Learn OpenGL ES
  • 4,759
  • 1
  • 36
  • 38
5

For those saying that the answer of @kuester2000 does not work, please be aware that HTTP requests, first try to find the host IP with a DNS request and then makes the actual HTTP request to the server, so you may also need to set a timeout for the DNS request.

If your code worked without the timeout for the DNS request it's because you are able to reach a DNS server or you are hitting the Android DNS cache. By the way you can clear this cache by restarting the device.

This code extends the original answer to include a manual DNS lookup with a custom timeout:

//Our objective
String sURL = "http://www.google.com/";
int DNSTimeout = 1000;
int HTTPTimeout = 2000;

//Get the IP of the Host
URL url= null;
try {
     url = ResolveHostIP(sURL,DNSTimeout);
} catch (MalformedURLException e) {
    Log.d("INFO",e.getMessage());
}

if(url==null){
    //the DNS lookup timed out or failed.
}

//Build the request parameters
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, HTTPTimeout);
HttpConnectionParams.setSoTimeout(params, HTTPTimeout);

DefaultHttpClient client = new DefaultHttpClient(params);

HttpResponse httpResponse;
String text;
try {
    //Execute the request (here it blocks the execution until finished or a timeout)
    httpResponse = client.execute(new HttpGet(url.toString()));
} catch (IOException e) {
    //If you hit this probably the connection timed out
    Log.d("INFO",e.getMessage());
}

//If you get here everything went OK so check response code, body or whatever

Used method:

//Run the DNS lookup manually to be able to time it out.
public static URL ResolveHostIP (String sURL, int timeout) throws MalformedURLException {
    URL url= new URL(sURL);
    //Resolve the host IP on a new thread
    DNSResolver dnsRes = new DNSResolver(url.getHost());
    Thread t = new Thread(dnsRes);
    t.start();
    //Join the thread for some time
    try {
        t.join(timeout);
    } catch (InterruptedException e) {
        Log.d("DEBUG", "DNS lookup interrupted");
        return null;
    }

    //get the IP of the host
    InetAddress inetAddr = dnsRes.get();
    if(inetAddr==null) {
        Log.d("DEBUG", "DNS timed out.");
        return null;
    }

    //rebuild the URL with the IP and return it
    Log.d("DEBUG", "DNS solved.");
    return new URL(url.getProtocol(),inetAddr.getHostAddress(),url.getPort(),url.getFile());
}   

This class is from this blog post. Go and check the remarks if you will use it.

public static class DNSResolver implements Runnable {
    private String domain;
    private InetAddress inetAddr;

    public DNSResolver(String domain) {
        this.domain = domain;
    }

    public void run() {
        try {
            InetAddress addr = InetAddress.getByName(domain);
            set(addr);
        } catch (UnknownHostException e) {
        }
    }

    public synchronized void set(InetAddress inetAddr) {
        this.inetAddr = inetAddr;
    }
    public synchronized InetAddress get() {
        return inetAddr;
    }
}
David Darias
  • 570
  • 6
  • 9
3

An option is to use the OkHttp client, from Square.

Add the library dependency

In the build.gradle, include this line:

compile 'com.squareup.okhttp:okhttp:x.x.x'

Where x.x.x is the desired library version.

Set the client

For example, if you want to set a timeout of 60 seconds, do this way:

final OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setReadTimeout(60, TimeUnit.SECONDS);
okHttpClient.setConnectTimeout(60, TimeUnit.SECONDS);

ps: If your minSdkVersion is greater than 8, you can use TimeUnit.MINUTES. So, you can simply use:

okHttpClient.setReadTimeout(1, TimeUnit.MINUTES);
okHttpClient.setConnectTimeout(1, TimeUnit.MINUTES);

For more details about the units, see TimeUnit.

androidevil
  • 9,011
  • 14
  • 41
  • 79
  • 1
    In the current version of OkHttp, timeouts need to be set differently: [https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/ConfigureTimeouts.java](https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/ConfigureTimeouts.java) – thijsonline Nov 29 '17 at 09:09
1
HttpParams httpParameters = new BasicHttpParams();
            HttpProtocolParams.setVersion(httpParameters, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(httpParameters,
                    HTTP.DEFAULT_CONTENT_CHARSET);
            HttpProtocolParams.setUseExpectContinue(httpParameters, true);

            // Set the timeout in milliseconds until a connection is
            // established.
            // The default value is zero, that means the timeout is not used.
            int timeoutConnection = 35 * 1000;
            HttpConnectionParams.setConnectionTimeout(httpParameters,
                    timeoutConnection);
            // Set the default socket timeout (SO_TIMEOUT)
            // in milliseconds which is the timeout for waiting for data.
            int timeoutSocket = 30 * 1000;
            HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
Sandeep
  • 766
  • 5
  • 16
1

If you are using the HttpURLConnection, call setConnectTimeout() as described here:

URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(CONNECT_TIMEOUT);
Rahul Sharma
  • 2,867
  • 2
  • 27
  • 40
Bruno Peres
  • 2,980
  • 1
  • 21
  • 19
  • The description is more like the timeout to establish the connection, instead of http request ? – ctk2021 Apr 24 '19 at 04:45
1

you can creat HttpClient instance by the way with Httpclient-android-4.3.5,it can work well.

 SSLContext sslContext = SSLContexts.createSystemDefault();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext,
                SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER);
                RequestConfig.Builder requestConfigBuilder = RequestConfig.custom().setCircularRedirectsAllowed(false).setConnectionRequestTimeout(30*1000).setConnectTimeout(30 * 1000).setMaxRedirects(10).setSocketTimeout(60 * 1000);
        CloseableHttpClient hc = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(requestConfigBuilder.build()).build();
foxundermon
  • 570
  • 7
  • 18
0
public boolean isInternetWorking(){
    try {
        int timeOut = 5000;
        Socket socket = new Socket();
        SocketAddress socketAddress = new InetSocketAddress("8.8.8.8",53);
        socket.connect(socketAddress,timeOut);
        socket.close();
        return true;
    } catch (IOException e) {
        //silent
    }
    return false;
}
Eco4ndly
  • 515
  • 1
  • 5
  • 22