Httpclient блокирует Apache на socketread даже с установленным soTimeout - PullRequest
0 голосов
/ 25 ноября 2011

Мне нужно получить несколько html-страниц по сети, и я использую httpclient apache из пакета http-components.Я установил connectionTimeout, soTimeout как 5000 миллисекунд, а также установил перенаправление на false, но кажется, что код блокируется в функции socketread.

Конкретные заблокированные URL приведены ниже: http://high.lrn.fm http://gotradioaac04.lbdns -streamguys.com

Может кто-нибудь дать мне какой-нибудь совет относительно того, как предотвратить блокировку потока при операции чтения из сокета httpclient

Myкод приведен ниже для справки

public class HTTPDataDownloader {

    private static final Logger logger          = Logger.getLogger(HTTPDataDownloader.class);
    private int                 soTimeout;                                                      // ms
    private int                 connTimeout;                                                    // ms
    private HttpParams          httpParameters;
    private HttpClient          httpClient;
    private static final String HTTP_CONTENT    = "text/html";

    public HTTPDataDownloader( int soTimeout, int connTimeout ) {
        this.soTimeout = soTimeout;
        this.connTimeout = connTimeout;
        initialize();
    }

    private void initialize() {
        httpParameters = new BasicHttpParams();
        // Set the timeout in milliseconds until a connection is established.
        HttpConnectionParams.setConnectionTimeout(httpParameters, connTimeout);
        // Set the default socket timeout (SO_TIMEOUT)
        // in milliseconds which is the timeout for waiting for data.
        HttpConnectionParams.setSoTimeout(httpParameters, soTimeout);
        HttpConnectionParams.setStaleCheckingEnabled(httpParameters, false);
        HttpConnectionParams.setLinger(httpParameters, 5);
        httpParameters.setParameter("http.protocol.handle-redirects",false);
        HttpClientParams.setRedirecting(httpParameters, false);
        //HttpClientParams.setConnectionManagerTimeout(httpParameters, 500);

        httpClient = new DefaultHttpClient(httpParameters);
        httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
    }

    private void setRetryHandler() {
        HttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(2, true);

        //httpClient.setHttpRequestRetryHandler(retryHandler);
        //httpClient.getParams().setParameter(HttpParams, arg1)
    }

    // takes the url, make the connection and fetch the data
    public String fetch( String urlname ) {
        urlname = formatURL(urlname);
        HttpGet httpget = new HttpGet();
        try {
            httpget.setURI(new URI(urlname));
        } catch ( URISyntaxException e ) {
            logger.error(e.toString());
            return null;
        }

        StringBuilder content = new StringBuilder();
        InputStream instream = null;
        try {
            HttpResponse httpResponse = httpClient.execute(httpget);
            HttpEntity entity = httpResponse.getEntity();
            if ( entity != null ) {

                String contentType = entity.getContentType().getValue();
                HeaderElementIterator it = new BasicHeaderElementIterator(
                                                                          httpResponse.headerIterator(HTTP.CONN_KEEP_ALIVE));
            /*  while (it.hasNext()) {
                    HeaderElement he = it.nextElement();
                    String param = he.getName(); 
                    String value = he.getValue();
                    if (value != null && param.equalsIgnoreCase("timeout")) {
                        System.out.println(value + urlname);
                    }
                }*/
                if ( contentType != null && contentType.indexOf(HTTP_CONTENT) >= 0 ) {
                    instream = entity.getContent();
                    BufferedReader br = new BufferedReader(new InputStreamReader(instream));
                    String line;
                    String newLine = System.getProperty("line.separator");

                    while ( (line = br.readLine()) != null )
                        content.append(line + newLine);
                    logger.info("Downloaded: " + httpget.getURI().toString());
                    return content.toString();
                }
            }
        }
        catch ( ClientProtocolException e ) {       
            logger.info("ClientProtocolException: " + e + " " + urlname);
        } catch ( ConnectTimeoutException e ) {
            logger.info("ConnectionTimeoutException: " + e + " " + urlname);
        } catch ( SocketTimeoutException e ) {
            logger.info("SocketTimeoutException: " + e + " " + urlname);
        } catch ( IOException e ) {
            logger.info("IOException: " + e + " " + urlname);
        } catch ( Exception e ) {
            logger.equals("Exception: " + e + " " + urlname);
        } finally {
            httpget.abort();    
            try {               
                if (instream != null)
                    instream.close(); 
            } catch ( IOException e ) { }
        }

        return null;
    }

1 Ответ

0 голосов
/ 19 мая 2017

Я также столкнулся с проблемой, потому что поток httpclient.execute не освобождает соединение. Вы можете попытаться добавить две строки после получения ответа:

httpget.releaseConnection();
httpclient.getConnectionManager().shutdown();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...