Android HttpURLConnection throwing EOFException

亡梦爱人 提交于 2019-11-27 21:41:33

问题


Here's the question in simplest way.

I create a HTTPS connection to my server through proxy using HttpUrlConnection Object.

My proxy closes the connection but my code still tries to reuse the same connection. And so I get EOFException.

How do I handle such cases?


回答1:


I'd recommend disabling the http.keepalive system property. The performance section of the documentation indicates that socket connections will be reused when possible. It sounds like it is trying to reuse the connection, but the proxy has already closed it. On this post, Darrell also indicates that changing the system property solved his problem.

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



回答2:


Turns out they've fixed this issue in Android on Jan 8th [1]. The fix basically marks the old connection as recycled and internally retries the request.

To fix this for now, I would suggest retrying requests if an EOFException is encountered with a retry limit to prevent stackoverlows.

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



回答3:


I had this problem with normal HTTP connections as well. The first request went OK, the second failed with an EOFException.

Eventuelly I fixed it by removing...

urlConnection.setChunkedStreamingMode(0);

...from the HttpUrlConnection.

I could be that the webserver I'm calling can't handle chuncked data well. Don't know.




回答4:


If you don't want to reuse the connection then release it.

finally {
     urlConnection.disconnect();
   }



回答5:


You can use this method to pick data from server then you convert the inputs trim to string then you can parse for further use.`

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



回答6:


Maybe httpClient "has more bugs" and is deprecated, but this problem with JellyBean is a showstopper. I am using Ksoap2 so I tried all the suggested answers that I could.

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

Nothing worked - my solution was to rollback the version of Ksoap2 I'm using from 3.1.1 to 2.6.5. Using 2.6.5 the problem is substantially reduced. Still testing but maybe even solved.




回答7:


I found that retrying the connection fixes the issue as seen here: https://stackoverflow.com/a/20302767/2520390

Make sure you close off the connection before your recursive call.

Also, I added the following to the connection to close the connection, though I'm not sure if it helps:

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



回答8:


You shouldn't be attempting to reuse the same HttpURLConnection instance. The docs in the very bottom line of the "Class Overview" say

Each instance of HttpURLConnection may be used for one request/response pair.

Keep-Alive connections work at a different level, see the disconnect docs: http://developer.android.com/reference/java/net/HttpURLConnection.html#disconnect()

Unlike other Java implementations, this will not necessarily close socket connections that can be reused. You can disable all connection reuse by setting the http.keepAlive system property to false before issuing any HTTP requests.

So you should always use a fresh HttpURLConnection and let the socket pool handle re-use.

There were apparently bugs with keep-alive connections pre-Froyo (2.2) so it is recommended to disable keep-alive on those old devices.

In my case the EOFException was caused by my server not sending a full response, see the details here: https://stackoverflow.com/a/27845172/2335025




回答9:


You shouldn't be attempting to reuse the same HttpURLConnection instance. The docs in the very bottom line of the "Class Overview" say

Each instance of HttpURLConnection may be used for one request/response pair.

Keep-Alive connections work at a different level, see the disconnect docs: http://developer.android.com/reference/java/net/HttpURLConnection.html#disconnect()

Unlike other Java implementations, this will not necessarily close socket connections that can be reused. You can disable all connection reuse by setting the http.keepAlive system property to false before issuing any HTTP requests.

So you should always use a fresh HttpURLConnection and let the socket pool handle re-use. There are perhaps issues if it tries to reuse a socket that has been closed by the server, which the answers to this question deal with: Android HttpUrlConnection EOFException

There were apparently bugs with keep-alive connections pre-Froyo (2.2) so it is recommended to disable keep-alive on those old devices.

In my case the EOFException was caused by my server not sending a full response, see the details here: https://stackoverflow.com/a/27845939/2335025




回答10:


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



回答11:


Try this code:`

Httppost method:

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

`




回答12:


to convert stream to string:`

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();

}`


来源:https://stackoverflow.com/questions/12319194/android-httpurlconnection-throwing-eofexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!