2012-08-09 4 views
24

다음 코드를 사용하여 서버에 요청을 보내려고합니다. 그것은 세 번째 요청에서 항상 실패했습니다. 다음과 같이httpclient exception "org.apache.http.conn.ConnectionPoolTimeoutException : 연결 대기 시간 초과"

import java.io.InputStreamReader; 
import java.io.UnsupportedEncodingException; 
import java.nio.charset.Charset; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.HttpStatus; 
import org.apache.http.HttpVersion; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.entity.ContentType; 
import org.apache.http.entity.StringEntity; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; 
import org.apache.http.params.BasicHttpParams; 
import org.apache.http.params.CoreConnectionPNames; 
import org.apache.http.params.HttpParams; 
import org.apache.http.params.HttpProtocolParams; 
import org.json.JSONException; 
import org.json.JSONObject; 
import org.json.JSONTokener; 

public class HttpClientTest { 
    private HttpClient client; 

    public HttpClientTest() { 
     HttpParams params = new BasicHttpParams(); 
     params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15000); 
     params.setParameter(CoreConnectionPNames.SO_TIMEOUT, 15000); 

     HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
     HttpProtocolParams.setContentCharset(params, "utf-8"); 
     HttpProtocolParams.setUseExpectContinue(params, true); 
     ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(); 
     cm.setMaxTotal(100); 
     client = new DefaultHttpClient(cm, params); 

     while (true) { 
      HttpPost mPost = new HttpPost("http://myip/myservice"); 

      JSONObject json = new JSONObject(); 
      try { 
       json.put("serialNumber", "abcd"); 
      } catch (JSONException e1) { 
       e1.printStackTrace(); 
      } 
      StringEntity s = null; 
      try { 
       s = new StringEntity(json.toString()); 
      } catch (UnsupportedEncodingException e) { 
       e.printStackTrace(); 
      }    
      s.setContentEncoding("UTF-8"); 
      s.setContentType("application/json"); 
      mPost.setEntity(s); 

      JSONObject response = null; 

      System.out.println("HttpClientTest ---> send post"); 
      HttpResponse mHttpResponse; 
      try { 
       mHttpResponse = client.execute(mPost); 
       System.out.println("HttpClientTest ---> get response"); 
       if(mHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ 
        HttpEntity entity = mHttpResponse.getEntity(); 
        ContentType contentType = ContentType.getOrDefault(entity); 
        Charset charset = contentType.getCharset(); 
        response = new JSONObject(new JSONTokener(new InputStreamReader(entity.getContent(), charset))); 

        System.out.println("HttpClientTest ---> get result:" + response.toString()); 
       } else { 
        mPost.abort(); 
        break; 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     HttpClientTest t = new HttpClientTest(); 
    } 
} 

예외 :

org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection 
    at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking(ConnPoolByRoute.java:417) 
    at org.apache.http.impl.conn.tsccm.ConnPoolByRoute$1.getPoolEntry(ConnPoolByRoute.java:300) 
    at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1.getConnection(ThreadSafeClientConnManager.java:224) 
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:401) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732) 
    at com.i360r.client.takeaway.network.HttpClientTest.<init>(HttpClientTest.java:68) 
    at com.i360r.client.takeaway.network.HttpClientTest.main(HttpClientTest.java:88) 
+1

이 문제를 해결할 수 있습니까? – CoronaPintu

+0

누군가 해결 했습니까? –

답변

22

나는 그것을 해결했습니다! finally 블록에 mPost.releaseConnection()을 추가하십시오.

try { 
} catch (Exception e) { 
} finally { 
    mPost.releaseConnection(); 
} 

내가 같은 문제를 가지고 내가 수정을 발견 org.apache.httpcomponents

39

4.2.1에 업데이트 패키지를 않습니다. 이 시간 초과는 연결 유출로 인해 발생합니다. 내 경우에는 httpDelete 메서드를 사용하고 응답을 소비하지 않습니다. 대신 응답 상태를 확인하십시오.

해결 방법은 응답 엔터티를 사용해야한다는 것입니다. 시스템 리소스의 적절한 해제를 보장하기 위해서는 엔티티와 관련된 콘텐츠 스트림을 닫아야합니다.

따라서 엔티티 콘텐츠가 완전히 사용되고 콘텐츠 스트림 (있는 경우)이 닫히는 것을 보장하기 위해 EntityUtils.consumeQuietly(response.getEntity());을 사용했습니다.

+1

응답을 무시할 때 Fluent HTTP 클라이언트에서 비슷한 문제가 발생했습니다. 연결 누출을 피하기 위해 여전히 execute(). discardContent()를 호출해야합니다. – rrhartjr

+4

매우 성가신 .... 도서관은 당신이 그것을 소비하지 않는다면 버려야합니다 ... 아니면 적어도 그것에 대해 경고를합니다 ... – nterry

2

당신이 장면 뒤에 기본 구성을 가진 MultiThreadedHttpConnectionManager를 생성 DropWizard 0.6.2로 ApacheHttpClient를 사용하는 경우도 발생할 수 있습니다 - 단 한 번 more info here에서 2 개 동시 HTTP 연결을 허용하는 기본 구성.

이렇게 구성하면 서버가 계속 침체되어 동일한 호스트에 요청하는 경우 한 번에 최대 2 개의 연결이 허용됩니다.