最近在做团购酒店APP分享到qzone功能,使用libcurl访问qzone的分享cgi接口,酒店分享信息以POST方式传输,在测试的时候发现分享接口平均有2s的延迟,这延迟也太大了吧,于是乎问了空间的接口人,答曰:怎么可能,这个接口的平均调用时延是100-200ms,肯定是你的代码有问题。好吧,开始检查代码,使用strace -p跟踪系统调用,发现curl发送了两次请求,其中第一次请求的响应特别的慢,额,原来这个才是导致延迟的罪魁祸首,tcpdump之后发现curl发送的第一个请求包含一个Expect: 100-continue的头,这是为什么呢,于是开始百度,google,得到的解释如下:

当使用libcurl的POST方式时,如果POST数据的大小大于1024个字节,libcurl不会直接发送POST请求,而是会分为两步执行请求:
1、发送一个请求,该请求头部包含一个Expect: 100-continue的字段,用来询问server是否愿意接受数据
2、当接收到从server返回的100-continue的应答后,它才会真正的发起POST请求,将数据发送给server。

对于“100-continue"这个字段,RFC文档(http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3)是这么解释的:它可以让客户端在发送请求数据之前去判断服务器是否愿意接收该数据,如果服务器愿意接收,客户端才会真正发送数据,这么做的原因是如果客户端直接发送请求数据,但是服务器又将该请求拒绝的话,这种行为将带来很大的资源开销。所以为了避免这种情况,libcurl在发送大于1024字节的POST请求时采用了这种方法,但是相对的,它会引起请求延迟的加大,另外并不是所有的server都会正确处理并且应答”100-continue“,比如lighttpd,就会返回417”Expectation Failed“,造成请求逻辑出错。

如果确定服务器不会拒绝1024个字节以上的POST请求,就可以不使用该方法而且也可以避免以上提到的两个副作用,解决的办法如下:

  1. // disable Expection header
  2. curl_easy_setopt(curl, CURLOPT_HTTPHEADER, array('Expect:'));

禁用该机制后,测试了一下qzone分享接口平均调用时延减小到了200ms,这才是正常的延时嘛,嘿嘿。
参考资料:
http://www.laruence.com/2011/01/20/1840.html

from:http://blog.csdn.net/zxgfa/article/details/7604624

libcurl发起post请求时间延迟问题。except为空即可的更多相关文章

  1. 在Windows上使用libcurl发起HTTP请求

    curl下载地址https://curl.haxx.se/download.html 当前最新版本为7.61.0 将下载的curl-7.61.0.zip解压,得到curl-7.61.0 在目录curl ...

  2. php 使用curl发起https请求

    今天一个同事反映,使用curl发起https请求的时候报错:“SSL certificate problem, verify that the CA cert is OK. Details: erro ...

  3. Ajax_02之XHR发起异步请求

    1.Ajax: AJAX:Asynchronous Javascript And Xml,异步的JS和XML: 同步请求:地址栏输入URL.链接跳转.表单提交-- 异步请求:使用Ajax发起,底层使用 ...

  4. python urllib2 发起http请求post

    使用urllib2发起post请求 def GetCsspToken(): data = json.dumps({"userName":"wenbin", &q ...

  5. 发起post请求

    string postUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo"; //string req ...

  6. 关于java发起http请求

    我们到底能走多远系列(41) 扯淡: 好久没总结点东西了,技术上没什么总结,感觉做事空牢牢的.最近也比较疲惫. 分享些东西,造福全人类~ 主题: 1,java模拟发起一个http请求 使用HttpUR ...

  7. 关于在页面总嵌入iframe,ifram中发起请求,服务器端的session为空问题解决

    本文抄袭:http://blog.csdn.net/ray_adon/article/details/6960724 在做项目是 是用了iframe,iframe发起ajax请求,服务器端报sessi ...

  8. [Java] 两种发起POST请求方法,并接收返回的响应内容的处理方式

    1.利用apache提供的commons-httpclient-3.0.jar包 代码如下: /** * 利用HttpClient发起POST请求,并接收返回的响应内容 * * @param url ...

  9. android4.0 HttpClient 以后不能在主线程发起网络请求

    android4.0以后不能在主线程发起网络请求,该异步网络请求. new Thread(new Runnable() { @Override public void run() { // TODO ...

随机推荐

  1. Unity中有两种Animation Clip

    http://blog.csdn.net/zzxiang1985/article/details/51291861 在Unity中,我们有两种方法创建Animation Clip. 一种(后面简称方法 ...

  2. laravel 中 与前端的一些事2 之使用Gulp编译sass

    下载所有依赖npm的packagist: 下载了前端laravel  elixir编译所需要的全部工具: gulp编译scss文件: scss文件的默认存放位置: 输入命令gulp 开始编译scss文 ...

  3. CentOS 6 使用 yum 安装MongoDB及服务器端配置

    安装MongoDB的方法有很多种,可以源代码安装,在Centos也可以用yum源安装的方法.由于MongoDB更新得比较快,我比较喜欢用yum源安装的方法.64位Centos下的安装步骤如下: 1.准 ...

  4. C++学习之:括号匹配与栈的使用

    #include <stack> using std::stack ; 变量定义: stack<T>  stackName ; 成员函数: 成员函数 功能 bool  empt ...

  5. 我也来SplashScreen

    SplashScreen,就是平时我们说的溅射屏幕,任何一个做过客户端程序的coder应该对它都不陌生,因为它能提升用户体验,让软件看上去更美.SplashScreenForm通常进入程序时是打开,主 ...

  6. MVC模式与三层架构的区别

    之前总是混淆MVC表现模式和三层架构模式,为此记录下. 三层架构和MVC是有明显区别的,MVC应该是展现模式(三个加起来以后才是三层架构中的UI层) 三层架构(3-tier application) ...

  7. iOS开发网络篇—文件的上传

    iOS开发网络篇—文件的上传 说明:文件上传使用的时POST请求,通常把要上传的数据保存在请求体中.本文介绍如何不借助第三方框架实现iOS开发中得文件上传. 由于过程较为复杂,因此本文只贴出部分关键代 ...

  8. redhat6.4上build storm 0.9.0.1

    1.安装mvn 2.下载源代码 3.build mvn package 过程中出现问题,clojars.org 访问不了.通过私服映射clojars.org并在pom.xml中将dependency的 ...

  9. VS2012 快捷键

    注释: Ctrl+K+C 反注释: Ctrl+K+U 折叠代码: Ctrl+M+O   展开代码: Ctrl+M+L 在文件中查找: Ctrl+Shift+F 选 EntireSolution 删除行 ...

  10. php中 -> 和 => 和 :: 的用法 以及 self 和 $this 的用法

    => 数组中 用于数组的 key 和 value之间的关系例如:$a = array( '0' => '1', '2' => '4',); echo $a['0'];echo $a[ ...