最近在做团购酒店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. MySQL默认数据库

    欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...

  2. callee

    首先解释callee 参考网站 http://www.css88.com/archives/1706 callee是arguments的一个成员,仅当函数正在执行的时候才可用,so用于递归也行 代码示 ...

  3. Stack的pop和push操作

    #include <stack> #include <cstdio> using namespace std; int main(){ stack<int> s; ...

  4. c#中对json数据的序列化和反序列化(笔记)

    今天遇到在后台中要获取json格式数据里的某些值,网上查了些资料: string jsonstr = _vCustomerService.LoadCustomerbyNumTotalData(quer ...

  5. HighCharts绘制图表

    <div id="TradeMoney"></div> <script> $(function () { initData(); }); fun ...

  6. WCF事务应用[转]

    在B2B的项目中,一般用户注册后,就有一个属于自己的店铺,此时,我们就要插入两张表, User和Shop表. 当然,要么插入成功,要么全失败. 第一步: 首先看一下项目的结构图: 第二步: 准备工作, ...

  7. c#网络通信框架networkcomms内核解析 序言

    NetworkComms网络通信框架序言 networkcomms是我遇到的写的最优美的代码,很喜欢,推荐给大家:) 基于networkcomms2.3.1开源版本( gplv3)协议,写了一些文章, ...

  8. sqlserver存储过程批量插入数据

    在系统中经常会遇到向数据库中批量插入数据情况,存储过程中没有数组,只有通过字符串分割循环插入,下面是一个本人研究的一个例子: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 c ...

  9. ExtJs中gridpanel分组后组名排序

    /** * 定义降序的groupingStore */ var DescGroupingStore = Ext.extend(Ext.data.GroupingStore, { groupDir : ...

  10. 初识selendroid

    Testerhome社区的lihuazhang对selendroid官网的部分内容进行了翻译和讲解. 以下内容均摘自lihuazhang.感谢lihuazhang的讲解.原文地址:https://gi ...