使用HttpClient的HTTP Post请求需要2秒,为什么?

pab*_*leu 41 android http httpclient

更新: 自己找到答案,见下文:-)

嗨,

我目前正在编写一个Android应用程序,它使用HTTP Post和AsyncTask在后台提交内容.为此我使用org.apache.http.client包.我的代码基于这个例子.

基本上,我的代码看起来像这样:

public void postData() {
    // Create a new HttpClient and Post Header
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("http://192.168.1.137:8880/form");

    try {
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
        nameValuePairs.add(new BasicNameValuePair("id", "12345"));
        nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        // Execute HTTP Post Request
        HttpResponse response = httpclient.execute(httppost);

    } catch (ClientProtocolException e) {
     Log.e(TAG,e.toString());
    } catch (IOException e) {
     Log.e(TAG,e.toString());
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是httpclient.execute(..)行需要大约1.5到3秒,我不明白为什么.仅使用HTTP Get请求页面大约需要80 ms左右,因此问题似乎不是网络延迟本身.

问题似乎也不在服务器端,我也尝试将数据发布到http://www.disney.com/同样慢的结果.Firebug在本地向我的服务器发送数据时显示1 ms的响应时间.

这种情况发生在模拟器和我的Nexus One上(均为Android 2.2).

如果你想查看完整的代码,我把它放在GitHub上.

它只是一个虚拟程序,只需按一下按钮就可以在后台使用AsyncTask进行HTTP Post.这是我的第一个Android应用程序,也是我的第一个Java代码很长一段时间.而且在整体上,也是我对Stackoverflow的第一个问题;-)

任何想法为什么httpclient.execute(httppost)花了这么长时间?

pab*_*leu 55

好吧,我自己解决了这个问题.我所要做的就是添加一个将HTTP版本设置为1.1的参数,如下所示:

HttpParams params = new BasicHttpParams();
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpClient httpclient = new DefaultHttpClient(params);
Run Code Online (Sandbox Code Playgroud)

我发现这要归功于来自和书虫的非常好的HttpHelper类和一些反复试验.

如果我没记错的话,HTTP 1.0会为每个请求打开一个新的TCP连接.这可以解释大的延迟吗?

HTTP POST请求现在通过WLAN需要50到150毫秒,而3G上需要300到500毫秒.

  • 而不是版本的解决方法 - 为什么这仍然有效? - 我建议更直接的解决方案,`httppost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE,false);` (12认同)
  • 虽然不是更快 (3认同)
  • 稍微简单(但等效):HttpProtocolParams.setVersion(params,HttpVersion.HTTP_1_1); (2认同)

小智 6

我不是在Android上,但我在使用httpclient 4.0.1的Windows平台上面临完全相同的问题,经过相当多的头部刮擦,我找到了解决方案.

HttpParams params = new BasicHttpParams();
//this how tiny it might seems, is actually absoluty needed. otherwise http client lags for 2sec.
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpClient httpClient = new DefaultHttpClient(params);
HttpResponse httpResponse;


HttpPost httpPost = new HttpPost("http://"+server+":"+port+"/");
StringEntity entity = new StringEntity(content, "utf-8");
entity.setContentType("text/plain; charset=utf-8"); 
httpPost.setEntity(entity);

httpResponse=httpClient.execute(httpPost);

String response = IOUtils.toString(httpResponse.getEntity().getContent(),encoding);
httpResponse.getEntity().consumeContent();

httpClient.getConnectionManager().shutdown();
return(response);
Run Code Online (Sandbox Code Playgroud)

我不知道为什么用HTTP1.1版本设置参数解决了这个问题.但确实如此.甚至更奇怪,如果执行HTTP Get请求,症状也没有显示出来.

无论如何,我希望这有助于一些人!

H