Android: connection timeout not working (connectio

2019-02-05 15:26发布

问题:

I have an application that connects to a server. I set a timeout, disconnected the device from internet and tried to execute the post request to see if the timeout was called, but the connection keeps waiting forever. This is my code:

private static final int TIMEOUT_OPS = 3000 ;
private HttpClient mHttpClient;

public String sendToken(String token) throws IOException, AuthenticationException {
    JSONArray jsonData = new JSONArray();
    jsonData.put(token);

    final HttpPost post = prepareJSONRequest(jsonData.toString(), SEND_TOKEN_METHOD);
    HttpClient httpClient = getConnection();
    Log.i(TAG, "Sending request");
    final HttpResponse resp;
    try{
        resp = httpClient.execute(post);
    }catch(Exception e){
        e.printStackTrace();
        return null;
    }
    Log.i(TAG, "Got response");
    ...
}

private HttpPost prepareJSONRequest(String rest_data, String method) throws AssertionError {
    AbstractHttpEntity entity = null;
    try {
        final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair(KEY_PARAM_METHOD, method));
        params.add(new BasicNameValuePair(KEY_PARAM_INPUT_TYPE, JSON));
        params.add(new BasicNameValuePair(KEY_PARAM_RESPONSE_TYPE, JSON));
        params.add(new BasicNameValuePair("rest_data", rest_data));
        entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
        final HttpPost post = new HttpPost(mServer);
        post.addHeader(entity.getContentType());
        post.setEntity(entity);
        return post;

    } catch (final UnsupportedEncodingException e) {
        // this should never happen.
        throw new AssertionError(e);
    }
}

private HttpClient getConnection() {
    if (mHttpClient == null) {
        // registers schemes for both http and https
        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
        HttpProtocolParams.setUseExpectContinue(params, false);
        HttpConnectionParams.setConnectionTimeout(params, TIMEOUT_OPS);
        HttpConnectionParams.setSoTimeout(params, TIMEOUT_OPS);
        ConnManagerParams.setTimeout(params, TIMEOUT_OPS);
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
        sslSocketFactory.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        if (!mNoCertValidation)
            registry.register(new Scheme("https", sslSocketFactory, 443));
        else
            registry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
        ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, registry);
        mHttpClient = new DefaultHttpClient(manager, params);

    }
    return mHttpClient;
}

If I execute this code, my log shows "Sending request", but doesn't print the exception or "Got response". Why doesn't it work?

回答1:

If you have no Internet the DNS request will fail, but you cannot control the DNS timeout. Eventually you should get an UnknownHostException, but this may take several minutes. In this case the best thing to do is to start a timer in a separate thread at the same time you make the HTTP request. If the timer goes off before the HTTP request has finished, you can abort the HTTP request.