2011-11-25 110 views
-1

我必须通过线路获取几个html页面,并且我使用http-components包中的apache httpclient。我已经将connectionTimeout,soTimeout设置为5000毫秒以及将重定向转为false,但代码似乎在套接字函数中被阻止。即使使用soTimeout设置Apache的httpclient阻塞在socketread上

特定网址的被封锁给出如下: http://high.lrn.fm http://gotradioaac04.lbdns-streamguys.com

任何人都可以给我任何意见,如何防止线程在插座块读取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; 
    } 
+0

第一个URL返回HTTP 302(永久移动)。这可能是相关的吗? – Gian

+0

是的,即使我检查了...这意味着该网址已移动,并需要重定向...但我关闭重定向操作系统认为这应该处理...但其他网址是什么导致疾病问题 –

+0

你设法找到解决方案或解决方法?我现在正在遇到一模一样的问题。只有当我尝试从Shoutcast网址获取时才会发生这种情况。 – csvan

回答

0

我也遇到了这个问题,因为httpclient.execute线程不释放con nection。您可以尝试在获得响应后添加两行:

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