: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 使用的几个注意事项的更多相关文章

  1. libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET

    libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET libcurl 多线程使用注意事项 分类: C/C++学习 2012-05-24 18:48 2843人 ...

  2. Linux libcurl安装及注意事项

    一.下载 官网下载地址 :  https://curl.haxx.se/download.html 选择最新的一个即可. 二.安装 1.解压 下载到的压缩包为curl-7.51.0.tar.gz,使用 ...

  3. linux信号处理及libcurl的坑

    前言:     最近有个项目, 需要访问第三方服务. 该服务是通过http的形式访问的, 为了安全和加密, 对方提供了一个加密用的C/C++库, 用于对参数进行处理.  鉴于此, 选用了C/C++语言 ...

  4. 【转载】linux信号处理及libcurl的坑

    转载自http://www.cnblogs.com/mumuxinfei/p/4363466.html 前言:     最近有个项目, 需要访问第三方服务. 该服务是通过http的形式访问的, 为了安 ...

  5. libcurl get post http

    一.              概念 1.         为什么要使用libcurl 1)        作为http的客户端,可以直接用socket连接服务器,然后对到的数据进行http解析,但要 ...

  6. qt5集成libcurl实现tftp和ftp的方法一:搭建环境(五篇文章)

    最近使用QT5做一个软件,要求实现tftp和ftp文件传输,使用QT5开发好UI界面等功能,突然发现QT5不直接提供tftp和ftp支持,无奈之下只好找第三方库来间接实现,根据网友的介绍,libcur ...

  7. 最全的libcurl库资源整理

    C++ 用libcurl库进行http 网络通讯编程 百度登陆协议分析!!!用libcurl来模拟百度登陆 C++使用libcurl做HttpClient 使用libcurl库进行HTTP的下载 li ...

  8. (转)libcurl库使用方法,好长,好详细。

    一.ibcurl作为是一个多协议的便于客户端使用的URL传输库,基于C语言,提供C语言的API接口,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP ...

  9. c++利用jsoncpp libcurl 构造http 包(原)

    我们手游要接入uc九游进行测试,要用http向uc那边的sdk 服务器post  json数据. 虽然他们提供了php,java还有c#的服务端demo,但是我们服务器是C++写的,我实在不想中间再转 ...

随机推荐

  1. mysql的查询缓存模式介绍

    mysql的查询缓存 查询是数据库技术中最常用的操作.查询操作的过程比较简单,首先从客户端发出查询的SQL语句,数据库服务端在接收到由客户端发来的 SQL语句后, 执行这条SQL语句,然后将查询到的结 ...

  2. lamp环境中的/到底是指的网站根目录还是linux的根

    在lamp中经常会用到 require,require_once等包含文件的语句. 如果你使用相对路径没有问题. 但是如果你使用了这样的语句就要小心了. 对于如图网站目录 require_once ' ...

  3. sql server 数据库基础学习心得 思维导图

  4. How to install Pygame for Python 3.4 on Ubuntu 14.04(转)

    First run this to install dependencies: sudo apt-get install mercurial python3-dev python3-numpy \ l ...

  5. 鸟哥的linux私房菜——第20章 启动流程、模块管理与loader

    20.1 Linux启动流程分析 Linux启动过程: 按下开机电源后计算机硬件主动读取BIOS来加载硬件信息以及硬件系统的自我测试,之后系统会主动读取第一个可启动的设备(由BIOS设置),此时就可以 ...

  6. 解决VS2015无法调试dotnet core项目

    dotnet core 1.0正式版和VS2015 update3安装后一直无法在VS中正常调试. 错误提示:The debugger's worker process (msvsmon.exe) u ...

  7. ASP.NET MVC轻教程 Step By Step 7——改进Write动作方法

    在上一节我们使用强类型视图改进Write视图获得更好的智能感知和代码重构,现在可以进一步的改进动作方法. Step 1. 数据模型绑定 在Save方法中我们使用Request来获取表单传送的值,其实可 ...

  8. jdbc 安装驱动

    在使用JDBC编程时需要连接数据库,导入JAR包是必须的,导入其它的jar包方法同样如此,导入的方法是 打开eclipse 1.右击要导入jar包的项目,点properties 2.左边选择java ...

  9. Quartz1.8.5例子(八)

    /* * Copyright 2005 - 2009 Terracotta, Inc. * * Licensed under the Apache License, Version 2.0 (the ...

  10. 解决Tomcat无法加载css和js等静态资源文件

    解决思路有两个 一是,你使用了Apache服务器,html不交给Tomcat处理,所以你找不到Html等静态资源,所以你先停掉阿帕奇,然后只用Tomcat猫试试. 二是,像我一样,使用了Jetty开发 ...