libcurl 使用的几个注意事项
注:libcurl 入门指南( the tutorial ): http://curl.haxx.se/libcurl/c/libcurl-tutorial.html
0. 为使用的curl url 加入确定的协议头
原文:
If you specify URL without protocol:// prefix, curl will attempt to guess what protocol you might want. It will then default to HTTP but try other protocols based on often-used host name prefixes. For example, for host names starting with "ftp." curl will assume
you want to speak FTP.
1. 把 curl_easy_perform() 回调数据直接写到文件里(FILE *)
原文:
libcurl offers its own default internal callback that will take care of the data if you don't set the callback with CURLOPT_WRITEFUNCTION. It will then simply output the received data to stdout. You can have the default callback write the data to a different
file handle by passing a 'FILE *' to a file opened for writing with the CURLOPT_WRITEDATA option.
源代码中的实现:
这样,就能够少写一个回调函数了(喂,你是有多懒啊),示比例如以下
FILE *fp;
fp = fopen("/root/test.bmp", "wb");
...
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
...
fclose(fp);
2. curl_easy_perform 返回值处理
使用 CURLOPT_ERRORBUFFER 保存错误, buf_size=CURL_ERROR_SIZE
或使用 curl_easy_strerror(res) (感觉这个简便)
演示样例:
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
{
printf("%s curl_easy_perform() error! \n", __FUNCTION__);
printf("error msg = %s\n", curl_easy_strerror(res));
curl_easy_cleanup(curl);
return -1;
}
3. 多线程环境配置 CURLOPT_NOSIGNAL
原文:
When using multiple threads you should set the CURLOPT_NOSIGNAL option to 1 for all handles. Everything will or might work fine except that timeouts are not honored during the DNS lookup - which you can work around by building libcurl with c-ares support. c-ares
is a library that provides asynchronous name resolves. On some platforms, libcurl simply will not function properly multi-threaded unless this option is set.
对于 CURLOPT_TIMEOUT(默认0), CURLOPT_CONNECTTIMEOUT(默认300)选项:
In unix-like systems, this might cause signals to be used unless CURLOPT_NOSIGNAL is set.
4. 设置 CURLOPT_VERBOSE、CURLOPT_HEADER 的必要性
原文:
There's one golden rule when these things occur: set the CURLOPT_VERBOSE option to 1. It'll cause the library to spew out the entire protocol details it sends, some internal info and some received protocol data as well (especially when using FTP). If you're
using HTTP, adding the headers in the received output to study is also a clever way to get a better understanding why the server behaves the way it does. Include headers in the normal body output with CURLOPT_HEADER set 1.
经试验:
设置 curl_easy_setopt(curl, CURLOPT_HEADER, 1L) 后,回调函数会返回 http头相关信息(原本是直接输出到stdout的)。考虑到还要过滤这些信息,所以还是不要设置这个了
5. curl post 注意事项
原文:
Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header. You can disable this header with CURLOPT_HTTPHEADER as usual.
解释:
当使用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)是这么解释的:
它能够让client在发送请求数据之前去推断server是否愿意接收该数据。假设server愿意接收,client才会真正发送数据,
这么做的原因是假设client直接发送请求数据,可是server又将该请求拒绝的话。这样的行为将带来非常大的资源开销。
所以为了避免这样的情况,libcurl在发送大于1024字节的POST请求时採用了这样的方法,可是相对的,它会引起请求延迟的加大,
另外并非全部的server都会正确处理而且应答”100-continue“,比方lighttpd,就会返回417”Expectation Failed“,造成请求逻辑出错。
解决的方法:
// POST数据的大于1024个字节
struct curl_slist *headerlist = NULL;
static const char buf[] = "Expect:";
headerlist = curl_slist_append(headerlist, buf); /* initalize custom header list */
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); /* set header*/
curl_slist_free_all(headerlist); /* free slist */
6. 回调函数的正确返回
return (size * nmemb);
原因:
Your callback function should return the number of bytes it "took care of". If that is not the exact same amount of bytes that was passed to it, libcurl will abort the operation and return with an error code.
假设回调函数中接收的数据有误,个人感觉能够返回0或者返回你已经处理的数据数。
由于源代码的处理例如以下:
/* If the previous block of data ended with CR and this block of data is
just a NL, then the length might be zero */
// len 为要发送给回调函数的数据长度
if(len) {
wrote = data->set.fwrite_func(ptr, 1, len, data->set.out);
}
else {
wrote = len;
}
if(wrote != len) {
failf(data, "Failed writing body (%zu != %zu)", wrote, len);
return CURLE_WRITE_ERROR;
}
libcurl 使用的几个注意事项的更多相关文章
- libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET
libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET libcurl 多线程使用注意事项 分类: C/C++学习 2012-05-24 18:48 2843人 ...
- Linux libcurl安装及注意事项
一.下载 官网下载地址 : https://curl.haxx.se/download.html 选择最新的一个即可. 二.安装 1.解压 下载到的压缩包为curl-7.51.0.tar.gz,使用 ...
- linux信号处理及libcurl的坑
前言: 最近有个项目, 需要访问第三方服务. 该服务是通过http的形式访问的, 为了安全和加密, 对方提供了一个加密用的C/C++库, 用于对参数进行处理. 鉴于此, 选用了C/C++语言 ...
- 【转载】linux信号处理及libcurl的坑
转载自http://www.cnblogs.com/mumuxinfei/p/4363466.html 前言: 最近有个项目, 需要访问第三方服务. 该服务是通过http的形式访问的, 为了安 ...
- libcurl get post http
一. 概念 1. 为什么要使用libcurl 1) 作为http的客户端,可以直接用socket连接服务器,然后对到的数据进行http解析,但要 ...
- qt5集成libcurl实现tftp和ftp的方法一:搭建环境(五篇文章)
最近使用QT5做一个软件,要求实现tftp和ftp文件传输,使用QT5开发好UI界面等功能,突然发现QT5不直接提供tftp和ftp支持,无奈之下只好找第三方库来间接实现,根据网友的介绍,libcur ...
- 最全的libcurl库资源整理
C++ 用libcurl库进行http 网络通讯编程 百度登陆协议分析!!!用libcurl来模拟百度登陆 C++使用libcurl做HttpClient 使用libcurl库进行HTTP的下载 li ...
- (转)libcurl库使用方法,好长,好详细。
一.ibcurl作为是一个多协议的便于客户端使用的URL传输库,基于C语言,提供C语言的API接口,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP ...
- c++利用jsoncpp libcurl 构造http 包(原)
我们手游要接入uc九游进行测试,要用http向uc那边的sdk 服务器post json数据. 虽然他们提供了php,java还有c#的服务端demo,但是我们服务器是C++写的,我实在不想中间再转 ...
随机推荐
- 利用toString做类型的判断
//利用toString做类型的判断 : /*var arr = []; alert( Object.prototype.toString.call(arr) == '[object Array]' ...
- React 学习资源分享 菜鸟刚学5天 博客写的不多 不懂写博客的套路
http://www.ruanyifeng.com/blog/2015/03/react.html 首先个人强烈推荐 阮一峰的React基础 细细过一遍,看得出大师的用心良苦 然后就开始看书般的过ht ...
- Go语言探险思考笔记
最近接触对象存储,国际上鼎鼎有名的Amazon S3还有Google Cloud Service在国内由于防火墙还有机房过远的问题,并不能投入生产使用.国内有名的对象存储,大家众所周知的七牛云,后台就 ...
- Java 高效检查一个数组中是否包含某个值
如何检查一个数组(未排序)中是否包含某个特定的值?在Java中,这是一个非常有用并又很常用的操作.同时,在StackOverflow中,有时一个得票非常高的问题.在得票比较高的几个回答中,时间复杂度差 ...
- code jam训练
https://code.google.com/codejam/contests.html http://student.csdn.net/mcs/programming_challenges
- deep learning framework(不同的深度学习框架)
常用的deep learning frameworks 基本转自:http://www.codeceo.com/article/10-open-source-framework.html 1. Caf ...
- MFC窗口分割以及各窗口间的通讯
一个偶然的机会又重新接触了MFC窗口的分割,自己结合资料重新写了一个窗口分割的程序,现将具体流程跟大家分享一下: 1.我们先创建一个MFC单文档类的程序,具体分割方式先将单文档整个客户区分成两行一列, ...
- 掌握C++基础
以下是笔者在ubuntu系统下编译运行通过的一些反应c++基础特性的例子,包括类,结构体,构造函数,析构函数,函数的重载,this指针,类的继承,虚函数,函数的覆盖和隐藏等.(由于格式问题代码中的乱码 ...
- 使用mysql-proxy代理实现msyql数据库读写分离
要实现读写分离,可以先看看如何实现mysql数据库主从:http://www.cnblogs.com/sustudy/p/4174189.html mysql-proxy下载地址(要看好对应版本):h ...
- 搭建DirectUi开发平台
DirectUi的效果可以使用GDI.GDI+.DirectX.OpenGL实现,常用的有GDI和GDI+,后两种有杀鸡用牛刀的感觉.在网络上能找到此方面的教材 现在的软件越来越多的有很炫目的界面,看 ...