Android - HttpUrlConnection没有关闭。最终导致SocketException

时间:2013-12-04 05:30:14

标签: java android httpurlconnection

我在运行Jellybean(4.1 - 4.3)的设备中遇到HttpUrlConnection的一些问题,其中连接未关闭并且在执行多次后导致SocketException“Too many open files”。

我确实调用了HttpUrlConnection.disconnect()并关闭了finally块中的所有Inputstream,Outputstream,Reader和Writers。

转到adb shell并执行netstat会显示应用程序创建的所有连接都处于CLOSE_WAIT状态。

InputStream inputStream = httpUrlConnection.getInputStream();

// After calling inputStream.read() then the problem occurs. I think the 
// inputstream doesn't get closed even after calling close in a finally block. 
// The InputStream is a ChunkedInputStream if that helps.

我尝试过在2.3.3,4.0.3和4.4上运行的其他设备,但没有遇到此问题。

还有其他方法可以手动关闭连接吗?

4 个答案:

答案 0 :(得分:11)

我终于找到了解决方法。似乎Jellybean在“Keep-Alive”连接上存在问题。我刚刚将Connection = Close添加到我的请求标题中,现在一切正常。做一个netstat,我看到连接现在正在关闭,由于“打开的文件太多”,我不再收到SocketException。

答案 1 :(得分:0)

你可能最好不要调用disconnect(),从而允许它进行HTTP连接池。

答案 2 :(得分:0)

检查您是否尝试过以下所有内容...... 可能会有一些东西丢失..另外一点也不应该有任何问题。

InputStream in;
HttpsURLConnection urlConnection =null;
try {
    URL url = new URL(Url);

    urlConnection = (HttpsURLConnection) url
                     .openConnection();
    //5 Second timeout
    urlConnection.setReadTimeout(5*1000);

    in = urlConnection.getInputStream();
    int responseCode = urlConnection.getResponseCode();

    if (responseCode != HttpURLConnection.HTTP_OK) {
         InputStream errInputStream = urlConnection.getErrorStream();
        //Print error message and response code..
         errInputStream.close();
    }
    in.close();
} catch (Exception e) {
    e.printStackTrace();
} finally{
    if(urlConnection != null)
        urlConnection.disconnect();
}

答案 3 :(得分:0)

尝试使用OkHttp

一旦添加了Maven依赖项,就可以执行以下操作来下载文件:

OkHttpClient okHttpClient = new OkHttpClient.Builder().build();

OutputStream output = null;

try {
  Request request   = new Request.Builder().url( download_url ).build();
  Response response = okHttpClient.newCall( request ).execute();

  if ( !response.isSuccessful() ) {
    throw new FileNotFoundException();
  }

  output = new FileOutputStream( output_path );

  output.write( response.body().bytes() );
}
finally {
  // Ensure streams are closed, even if there's an exception.
  if ( output != null ) output.flush();
  if ( output != null ) output.close();
}

切换到OkHttp会立即解决我们泄漏的文件描述符问题,因此即使您被卡住了也值得尝试,即使以增加另一个库依赖项为代价。