Java 阿帕奇';即使设置了soTimeout,也会在socketread上阻塞httpclient

Java 阿帕奇';即使设置了soTimeout,也会在socketread上阻塞httpclient,java,httpclient,blocking,Java,Httpclient,Blocking,我必须通过网络获取一些html页面,并且我正在从http组件包使用apache的httpclient。我已经将connectionTimeout设置为5000毫秒,并将重定向设置为false,但是代码似乎在socketread函数中被阻塞 被阻止的特定url如下所示: 有谁能给我一些建议,如何防止线程阻塞httpclient的套接字读取操作 下面给出了我的代码供参考 public class HTTPDataDownloader { private static final Logg

我必须通过网络获取一些html页面,并且我正在从http组件包使用apache的httpclient。我已经将connectionTimeout设置为5000毫秒,并将重定向设置为false,但是代码似乎在socketread函数中被阻塞

被阻止的特定url如下所示:

有谁能给我一些建议,如何防止线程阻塞httpclient的套接字读取操作

下面给出了我的代码供参考

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

我也遇到了这个问题,因为httpclient.execute线程没有释放连接。您可以在收到响应后尝试添加两行:

httpget.releaseConnection();
httpclient.getConnectionManager().shutdown();

第一个URL返回HTTP 302(永久移动)。这可能是相关的吗?是的,甚至我检查过了…这意味着url已经移动,需要重定向…但我关闭了重定向操作系统认为这应该得到处理…但另一个url是导致问题的原因。您是否找到了解决方案或解决方法?我也有同样的问题。只有当我尝试从Shoutcast URL获取时,才会发生这种情况。“代码似乎在socketread函数中被阻塞”。你有什么证据?