Java에서 Android에 대한 HttpResponse 시간 초과를 설정하는 방법


333

연결 상태를 확인하기 위해 다음 기능을 만들었습니다.

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());
        ...

테스트를 위해 서버를 종료하면 실행 시간이 오래 걸립니다.

HttpResponse response = httpClient.execute(method);

너무 오래 기다리지 않기 위해 타임 아웃을 설정하는 방법을 아는 사람이 있습니까?

감사!

답변:


625

이 예에서는 두 개의 시간 초과가 설정되었습니다. 연결 시간 초과가 발생 java.net.SocketTimeoutException: Socket is not connected하고 소켓 시간이 초과되었습니다 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);

기존 HTTPClient (예 : DefaultHttpClient 또는 AndroidHttpClient)의 매개 변수를 설정하려면 setParams () 함수를 사용할 수 있습니다 .

httpClient.setParams(httpParameters);

1
@ 토마스 : 귀하의 사용
사례에

3
연결 시간이 초과되면 HttpResponse가 무엇을 반환합니까? 일단 HTTP 요청이 이루어지면 호출이 돌아올 때 상태 코드를 확인하지만 호출 시간이 초과되면이 코드를 확인할 때 NullPointerException이 발생합니다 ... 기본적으로 호출 할 때 상황을 처리하는 방법 시간이 초과됩니까? (저는 귀하의 답변과 매우 유사한 코드를 사용하고 있습니다)
Tim

10
@jellyfish-문서화에도 불구하고 AndroidHttpClient는 DefaultHttpClient를 확장 하지 않습니다 . 오히려 HttpClient를 구현합니다. setParams (HttpParams) 메소드를 사용하려면 DefaultHttpClient를 사용해야합니다.
Ted Hopp 2018 년

3
이봐, 훌륭한 답변 감사합니다. 그러나 연결 시간이 초과되면 사용자에게 토스트를 표시하고 싶습니다 ... 연결 시간이 초과되면 감지 할 수있는 방법은 무엇입니까?
Arnab Chakraborty

2
작동하지 않습니다. 나는 내 소니와 모토에서 테스트를했는데 모두 뭉쳤다.
thecr0w

13

클라이언트에서 설정을 설정하려면

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

나는 이것을 JellyBean에서 성공적으로 사용했지만 이전 플랫폼에서도 작동해야합니다 ....

HTH


HttpClient와의 관계는 무엇입니까?
Sazzad Hissain Khan

8

Jakarta의 http 클라이언트 라이브러리 를 사용하는 경우 다음과 같은 작업을 수행 할 수 있습니다.

        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);

5
HttpClientParams.CONNECTION_MANAGER_TIMEOUT을 알 수 없음
Tawani


찾는 방법? 기기가 Wi-Fi에 연결되어 있지만 실제로 Wi-Fi를 통해 전송되는 활성 데이터는 아닙니다.
Ganesh Katikar


5

@ kuester2000의 답변이 효과가 없다고 말하는 사람들은 HTTP 요청에 먼저 DNS 요청으로 호스트 IP를 찾은 다음 서버에 실제 HTTP 요청을 시도하십시오. DNS 요청 시간이 초과되었습니다.

DNS 요청에 대한 시간 초과없이 코드가 작동하면 DNS 서버에 연결할 수 있거나 Android DNS 캐시에 도달했기 때문입니다. 그런데 장치를 다시 시작하여이 캐시를 지울 수 있습니다.

이 코드는 사용자 정의 시간 초과와 함께 수동 DNS 조회를 포함하도록 원래 답변을 확장합니다.

//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

사용 된 방법 :

//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());
}   

이 수업은 이 블로그 게시물에 있습니다. 당신이 그것을 사용할 경우 가서 비고를 확인하십시오.

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;
    }
}

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);

완전하지 않은. HttpClient와의 관계는 무엇입니까?
Sazzad Hissain Khan 2015 년

1

Httpclient-android-4.3.5를 사용하여 HttpClient 인스턴스를 만들면 잘 작동 할 수 있습니다.

 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();

1

옵션은 Square에서 OkHttp 클라이언트 를 사용하는 입니다.

라이브러리 의존성 추가

build.gradle에서 다음 줄을 포함하십시오.

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

x.x.x원하는 라이브러리 버전은 어디에 있습니까 ?

클라이언트 설정

예를 들어 시간 제한을 60 초로 설정하려면 다음과 같이하십시오.

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

ps : minSdkVersion이 8보다 큰 경우을 사용할 수 있습니다 TimeUnit.MINUTES. 따라서 다음을 간단히 사용할 수 있습니다.

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

단위에 대한 자세한 내용은 TimeUnit을 참조하십시오 .


현재 버전의 OkHttp에서 시간 초과는 다르게 설정해야합니다. https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/ConfigureTimeouts.java
thijsonline

1

를 사용하는 경우 여기에 설명 된대로 HttpURLConnection전화 하십시오 .setConnectTimeout()

URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(CONNECT_TIMEOUT);

설명은 http 요청 대신 연결을 설정하는 시간 초과와 비슷합니다.
user2499800

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;
}

어떤 서버를 나타 냅니까? "8.8.8.8", 53
Junaed
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.