这是最简单的问题。
我使用 HttpUrlConnection 对象通过代理创建到我的服务器的 HTTPS 连接。
我的代理关闭了连接,但我的代码仍然尝试重用相同的连接。所以我得到了EOFException。
我该如何处理这种情况?
这是最简单的问题。
我使用 HttpUrlConnection 对象通过代理创建到我的服务器的 HTTPS 连接。
我的代理关闭了连接,但我的代码仍然尝试重用相同的连接。所以我得到了EOFException。
我该如何处理这种情况?
结果他们已经在 1 月 8 日 [1] 在 Android 中修复了这个问题。该修复基本上将旧连接标记为已回收并在内部重试请求。
为了暂时解决这个问题,我建议在遇到 EOFException 时重试请求,并设置重试限制以防止 stackoverlows。
正常的 HTTP 连接也有这个问题。第一个请求正常,第二个请求失败并出现 EOFException。
最终我通过删除...修复了它
urlConnection.setChunkedStreamingMode(0);
...来自 HttpUrlConnection。
我可能是我正在调用的网络服务器无法很好地处理分块数据。不知道。
如果您不想重用连接,请释放它。
finally {
urlConnection.disconnect();
}
您可以使用此方法从服务器中选择数据,然后将输入修剪转换为字符串,然后您可以解析以供进一步使用。`
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();
}
您不应该尝试重用相同的 HttpURLConnection 实例。“类概述”最底线的文档说
HttpURLConnection 的每个实例都可以用于一个请求/响应对。
Keep-Alive 连接工作在不同的级别,请参阅断开连接文档:http: //developer.android.com/reference/java/net/HttpURLConnection.html#disconnect()
与其他 Java 实现不同,这不一定会关闭可重用的套接字连接。您可以通过在发出任何 HTTP 请求之前将 http.keepAlive 系统属性设置为 false 来禁用所有连接重用。
因此,您应该始终使用新的 HttpURLConnection 并让套接字池处理重用。如果它尝试重用已被服务器关闭的套接字,可能会出现问题,这个问题的答案涉及:Android HttpUrlConnection EOFException
在 Froyo (2.2) 之前,keep-alive 连接显然存在错误,因此建议在这些旧设备上禁用 keep-alive。
在我的情况下,EOFException 是由我的服务器未发送完整响应引起的,请参阅此处的详细信息:https ://stackoverflow.com/a/27845939/2335025
您不应该尝试重用相同的 HttpURLConnection 实例。“类概述”最底线的文档说
HttpURLConnection 的每个实例都可以用于一个请求/响应对。
Keep-Alive 连接工作在不同的级别,请参阅断开连接文档:http: //developer.android.com/reference/java/net/HttpURLConnection.html#disconnect()
与其他 Java 实现不同,这不一定会关闭可重用的套接字连接。您可以通过在发出任何 HTTP 请求之前将 http.keepAlive 系统属性设置为 false 来禁用所有连接重用。
因此,您应该始终使用新的 HttpURLConnection 并让套接字池处理重用。
在 Froyo (2.2) 之前,keep-alive 连接显然存在错误,因此建议在这些旧设备上禁用 keep-alive。
在我的情况下,EOFException 是由我的服务器未发送完整响应引起的,请参阅此处的详细信息:https ://stackoverflow.com/a/27845172/2335025
我发现重试连接可以解决问题,如下所示:https ://stackoverflow.com/a/20302767/2520390
确保在递归调用之前关闭连接。
此外,我在连接中添加了以下内容以关闭连接,但我不确定它是否有帮助:
if (retries > 0) {
connection.setRequestProperty("Connection", "close");
}
也许httpClient
“有更多错误”并且已被弃用,但 JellyBean 的这个问题是一个引人注目的问题。我正在使用 Ksoap2,所以我尝试了所有建议的答案。
System.setProperty("http.keepAlive", "false");
httpTransportSE.getServiceConnection().setRequestProperty("Connection", "close");
httpTransportSE.getServiceConnection().disconnect();
没有任何效果 - 我的解决方案是将我正在使用的 Ksoap2 版本从 3.1.1 回滚到 2.6.5。使用 2.6.5 大大减少了问题。仍在测试,但甚至可能已解决。
if (Build.VERSION.SDK != null
&& Build.VERSION.SDK_INT > 13) {
con.setRequestProperty("Connection", "close");
}
试试这个代码:`
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();
}
`
将流转换为字符串:`
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();
}`