【发布时间】:2012-02-29 19:26:51
【问题描述】:
我正在努力解决以下问题: 我的应用程序使用 HttpClient 向 http 服务器发出一系列请求。我使用 HttpPut 向服务器发送数据。 第一个请求进展顺利,第二个请求挂起 40 秒,然后我捕获 Connection timed out 异常。我正在尝试重用我的 HttpClient 并通过同一个实例发送第二个请求。如果我创建新的 HttpClient 和新的 ConnectionManager,那么一切正常。
为什么会这样?以及如何解决它而不是每次都创建新的HttpClient?
提前致谢。
这是我的代码:(如果我在 doPut 中注释 readClient = newHttpClient(readClient),那么问题就出现了。
public class WebTest
{
private HttpClient readClient;
private SchemeRegistry httpreg;
private HttpParams params;
private URI url; //http://my_site.net/data/
protected HttpClient newHttpClient(HttpClient oldClient)
{
if(oldClient != null)
oldClient.getConnectionManager().shutdown();
ClientConnectionManager cm = new SingleClientConnManager(params, httpreg);
return new DefaultHttpClient(cm, params);
}
protected String doPut(String data)
{
//****************************
//Every time we need to send data, we do new connection
//with new ConnectionManager and close old one
readClient = newHttpClient(readClient);
//*****************************
String responseS = null;
HttpPut put = new HttpPut(url);
try
{
HttpEntity entity = new StringEntity(data, "UTF-8");
put.setEntity(entity);
put.setHeader("Content-Type", "application/json; charset=utf-8");
put.setHeader("Accept", "application/json");
put.setHeader("User-Agent", "Apache-HttpClient/WebTest");
responseS = readClient.execute(put, responseHandler);
}
catch(IOException exc)
{
//error handling here
}
return responseS;
}
public WebTest()
{
httpreg = new SchemeRegistry();
Scheme sch = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80);
httpreg.register(sch);
params = new BasicHttpParams();
ConnPerRoute perRoute = new ConnPerRouteBean(10);
ConnManagerParams.setMaxConnectionsPerRoute(params, perRoute);
ConnManagerParams.setMaxTotalConnections(params, 50);
ConnManagerParams.setTimeout(params, 15000);
int timeoutConnection = 15000;
HttpConnectionParams.setConnectionTimeout(params, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 40000;
HttpConnectionParams.setSoTimeout(params, timeoutSocket);
}
private ResponseHandler<String> responseHandler = new ResponseHandler<String>()
{
@Override
public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException
{
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() >= 300)
{
throw new HttpResponseException(statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
HttpEntity entity = response.getEntity();
if(entity == null)
return null;
InputStream instream = entity.getContent();
return this.toString(entity, instream, "UTF-8");
}
public String toString(
final HttpEntity entity,
final InputStream instream,
final String defaultCharset) throws IOException, ParseException
{
if (entity == null)
{
throw new IllegalArgumentException("HTTP entity may not be null");
}
if (instream == null)
{
return null;
}
if (entity.getContentLength() > Integer.MAX_VALUE)
{
throw new IllegalArgumentException("HTTP entity too large to be buffered in memory");
}
int i = (int)entity.getContentLength();
if (i < 0)
{
i = 4096;
}
String charset = EntityUtils.getContentCharSet(entity);
if (charset == null)
{
charset = defaultCharset;
}
if (charset == null)
{
charset = HTTP.DEFAULT_CONTENT_CHARSET;
}
Reader reader = new InputStreamReader(instream, charset);
StringBuilder buffer=new StringBuilder(i);
try
{
char[] tmp = new char[1024];
int l;
while((l = reader.read(tmp)) != -1)
{
buffer.append(tmp, 0, l);
}
} finally
{
reader.close();
}
return buffer.toString();
}
};
}
【问题讨论】:
-
服务器可能正在关闭您的连接。什么是响应头?
-
服务器甚至没有收到我的第二个请求
-
consumeContent() 是答案,感谢您的提问
-
如何使用 okHttp 库实现这一点,我正在进行同步网络调用。这里是同步调用代码 response = okHttpClient.newCall(request).execute();
标签: android httpclient