Android HttpURLConnection抛出EOFException

时间:2012-09-07 13:34:43

标签: android httpurlconnection eofexception

这是最简单的问题。

我使用HttpUrlConnection对象通过代理创建与服务器的HTTPS连接。

我的代理关闭连接,但我的代码仍尝试重用相同的连接。所以我得到了EOFException。

我该如何处理此类案件?

12 个答案:

答案 0 :(得分:9)

我建议禁用http.keepalive系统属性。 documentation的性能部分表示在可能的情况下将重用套接字连接。听起来它试图重用连接,但代理已经关闭了它。在this post,Darrell还表示更改系统属性解决了他的问题。

System.setProperty("http.keepAlive", "false");

答案 1 :(得分:6)

原来他们已经在1月8日在Android中解决了这个问题[1]。该修复程序基本上将旧连接标记为已回收并在内部重试请求。

要解决此问题,我建议在遇到重试限制的EOFException时重试请求以防止stackoverlow。

  1. https://android.googlesource.com/platform/libcore/+/19aa40c81c48ff98ccc7272f2a3c41479b806376

答案 2 :(得分:4)

我也遇到了普通HTTP连接的问题。第一个请求没问题,第二个请求因EOFException而失败。

Eventuelly我通过移除来修复它......

urlConnection.setChunkedStreamingMode(0);

...来自HttpUrlConnection。

我可能是因为我正在调用的网络服务器无法很好地处理chuncked数据。不知道。

答案 3 :(得分:1)

如果您不想重复使用该连接,请将其释放。

finally {
     urlConnection.disconnect();
   }

答案 4 :(得分:0)

您可以使用此方法从服务器中选择数据,然后将输入trim转换为字符串,然后您可以解析以供进一步使用。

  public static InputStream getUrlData(final String url)
        throws URISyntaxException, ClientProtocolException, IOException {
    final DefaultHttpClient client = new DefaultHttpClient();
    final HttpGet method = new HttpGet(new URI(url));
    final HttpResponse res = client.execute(method);
    return res.getEntity().getContent();
    }

答案 5 :(得分:0)

也许httpClient“有更多错误”并且已弃用,但JellyBean的这个问题是一个showstopper。我正在使用Ksoap2所以我尝试了所有建议的答案。

  • System.setProperty("http.keepAlive", "false");
  • httpTransportSE.getServiceConnection().setRequestProperty("Connection", "close");
  • httpTransportSE.getServiceConnection().disconnect();

没有任何效果 - 我的解决方案是将我使用的Ksoap2版本从3.1.1回滚到2.6.5。使用2.6.5可以大大减少问题。仍在测试,但甚至可能已经解决。

答案 6 :(得分:0)

我发现重试连接修复了此处出现的问题:https://stackoverflow.com/a/20302767/2520390

确保在递归调用之前关闭连接。

此外,我在连接中添加了以下内容以关闭连接,但我不确定它是否有帮助:

if (retries > 0) {
    connection.setRequestProperty("Connection", "close");
}

答案 7 :(得分:0)

您不应该尝试重用相同的HttpURLConnection实例。 {"班级概述"最底线的docs

  

HttpURLConnection的每个实例都可以用于一个   请求/响应对。

Keep-Alive连接在不同级别工作,请参阅disconnect文档: http://developer.android.com/reference/java/net/HttpURLConnection.html#disconnect()

  

与其他Java实现不同,这不一定会关闭   可以重用的套接字连接。您可以禁用所有连接   通过在之前将http.keepAlive系统属性设置为false来重用   发出任何HTTP请求。

所以你应该总是使用一个新的HttpURLConnection并让套接字池处理重用。

在Froyo(2.2)之前显然存在保持活动连接的错误,因此建议在这些旧设备上禁用keep-alive。

在我的情况下,EOFException是由我的服务器未发送完整响应引起的,请参阅此处的详细信息:https://stackoverflow.com/a/27845172/2335025

答案 8 :(得分:0)

您不应该尝试重用相同的HttpURLConnection实例。 {"班级概述"最底线的docs

  

HttpURLConnection的每个实例都可以用于一个   请求/响应对。

Keep-Alive连接在不同级别工作,请参阅disconnect文档: http://developer.android.com/reference/java/net/HttpURLConnection.html#disconnect()

  

与其他Java实现不同,这不一定会关闭   可以重用的套接字连接。您可以禁用所有连接   通过在之前将http.keepAlive系统属性设置为false来重用   发出任何HTTP请求。

所以你应该总是使用一个新的HttpURLConnection并让套接字池处理重用。如果它试图重用已被服务器关闭的套接字,则可能存在问题,该问题的答案涉及:Android HttpUrlConnection EOFException

在Froyo(2.2)之前显然存在保持活动连接的错误,因此建议在这些旧设备上禁用keep-alive。

在我的情况下,EOFException是由我的服务器未发送完整响应引起的,请参阅此处的详细信息:https://stackoverflow.com/a/27845939/2335025

答案 9 :(得分:0)

  if (Build.VERSION.SDK != null
                        && Build.VERSION.SDK_INT > 13) {
                    con.setRequestProperty("Connection", "close");
                }

答案 10 :(得分:-1)

试试这段代码:`

Httppost方法:

    HttpParams httpParams = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(httpParams, TIMEOUT_MILLISEC);
    HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT_MILLISEC);
    HttpClient client = new DefaultHttpClient(httpParams);
    HttpPost request = new HttpPost("put_url");
    request.setHeader("Content-Type", "application/xml");

    String file = resourceXml();


    StringEntity se = null;
    try {
        se = new StringEntity(file);
    } catch (UnsupportedEncodingException e1) {

        e1.printStackTrace();
    }

    se.setContentEncoding("UTF-8");
    se.setContentType("application/xml");
    request.setEntity(se);
    HttpResponse response = null;
    try {
        response = client.execute(request);
    } catch (ClientProtocolException e1) {

        e1.printStackTrace();
    } catch (IOException e1) {

        e1.printStackTrace();
    }

    HttpEntity entity = response.getEntity();
    InputStream is = null;
    try {
        is = entity.getContent();
    } catch (IllegalStateException e) {

        e.printStackTrace();
    } catch (IOException e) {

        e.printStackTrace();
    }
    String _response = convertStreamToString(is);

    Log.i(TAG, "Response:" + _response);
    // Check if server response is valid code
    int res_code = response.getStatusLine().getStatusCode();
    Log.i(TAG, "status_code" + res_code);
    try {
        is.close();
    } catch (IOException e) {

        e.printStackTrace();
    }

`

答案 11 :(得分:-1)

将流转换为字符串:`

private static String convertStreamToString(InputStream is) {

    BufferedReader reader = new BufferedReader(new InputStreamReader(is),
            8192);
    StringBuilder sb = new StringBuilder();

    String line = null;
    try {
        while ((line = reader.readLine()) != null) {
            sb.append((line + "\n"));
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return sb.toString();

}`