Notice: Function wp_enqueue_script was called incorrectly. Scripts and styles should not be registered or enqueued until the wp_enqueue_scripts, admin_enqueue_scripts, or login_enqueue_scripts hooks. This notice was triggered by the jquery handle. Please see Debugging in WordPress for more information. (This message was added in version 3.3.0.) in /mnt/webroot/wandoer/code.wandoer/wp-includes/functions.php on line 6260
libcurl 使用笔记 – 豌豆

libcurl 使用笔记

作者:

在

libcurl 是一个免费开源的 客户端 的网络传输库,它支持多种协议,包括
DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP等,还支持 SSL 认证。它简单好用,用它自己的话来说,就是 free, thread-safe, IPv6 compatible, feature rich, well supported, fast, thoroughly documented and is already used by many known, big and successful companies and
numerous applications。

1 基本流程

使用 libcurl 的一般流程:

  1. curl_global_init() 进行库的初始化
  2. curl_easy_init() 获取CURL* 指针
  3. curl_easy_setopt() 设置传输参数,包括回调等
  4. curl_easy_perform() 完成传输
  5. curl_easy_cleanup() 释放内存
  6. curl_global_cleanup() 释放库内存

我们需要着重关心的,是第 3 步。在这一步里,我们将指定 libcurl 如何将参数传递给服务端。

1.1 简单示例

#include <iostream>
#include "curl/curl.h"

using namespace std;

size_t read_callback(char *buffer, size_t size, size_t nitems, void *instream) 
{
        cout << buffer << endl;
        return size * nitems;
}

int main(void) 
{

        curl_global_init(CURL_GLOBAL_ALL);
        CURL* handle = curl_easy_init();
        if (!handle)
        {
                cout << "curl_easy_init error" << endl;
        }

        struct curl_slist* headers = NULL;
        curl_slist_append(headers, "user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) \
                                                Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0");
        curl_slist_append(headers, "accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");

        curl_easy_setopt(handle, CURLOPT_URL, "http://curl.haxx.se/");
        curl_easy_setopt(handle, CURLOPT_HEADER, 1L);
        curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(handle, CURLOPT_READFUNCTION, read_callback);

        CURLcode status = curl_easy_perform(handle);
        if (status != CURLE_OK) 
        {
                cout << "curl_easy_perform Error:" << status << endl;
        }
        curl_easy_cleanup(handle);

        curl_global_cleanup();

        return 0;
}

2 curl_easy API 介绍

2.1 curl_easy_setopt 的参数

2.1.1 CURLOPT_URL

设置访问 URL

2.1.2 CURLOPT_POST

非 0 则认为本次操作方法为 POST (即发起一个 POST request)

2.1.3 CURLOPT_PUT

非 0 则认为本次操作方法是 PUT

2.1.4 CURLOPT_POSTFIELDS

传递给 server 的 POST data

2.1.5 CURLOPT_HTTPPOST

告知 curl 以 multipart/formdata HTTP POST 的方式传递数据。(同时自动将 CURLOPT_NOBODY 设置为 0 )

/* Fill in the file upload field. This makes libcurl load data from
   the given file name when curl_easy_perform() is called. */
curl_formadd(&formpost,
             &lastptr,
             CURLFORM_COPYNAME, "sendfile",
             CURLFORM_FILE, "postit2.c",
             CURLFORM_END);

/* Fill in the filename field */
curl_formadd(&formpost,
             &lastptr,
             CURLFORM_COPYNAME, "filename",
             CURLFORM_COPYCONTENTS, "postit2.c",
             CURLFORM_END);

/* Fill in the submit field too, even if this is rarely needed */
curl_formadd(&formpost,
             &lastptr,
             CURLFORM_COPYNAME, "submit",
             CURLFORM_COPYCONTENTS, "send",
             CURLFORM_END);

2.1.6 CURLOPT_VERBOSE

非 0 则打印相关的详细信息

2.1.7 CURLOPT_HEADER

非 0 将响应头信息同响应体一起传给WRITEFUNCTION

2.1.8 CURLOPT_WRITEFUNCTION

对返回的数据进行操作的函数指针 回调函数的原型为:

size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_WRITEFUNCTION, write_callback);

当curl接收到数据时,回调被调用,参数 ptr 指向推送过来的数据,数据大小是 size 和 nmemb 的乘积。每次接收到的数据的大小可能都不一样,最大的大小在 curl.h 中定义(CURL_MAX_WRITE_SIZE默认16K ). 回调的最后一个参数 userdata由用户通过CURLOPT_WRITEDATA来指定,在回调中,可以将数据写入到 userdata 中。

2.1.9 CURLOPT_WRITEDATA

设置WRITEFUNCTION的第四个参数值

2.1.10 CURLOPT_TIMEOUT / CURLOPT_CONNECTIONTIMEOUT

传输超时时间 / 连接超时时间

2.1.11 CURLOPT_FOLLOWLOCATION

重定位URL

2.1.12 CURLOPT_NOSIGNAL

当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。

2.1.13 CURLOPT_HEADERFUNCTION

设置http header 的回调函数指针。回调函数原型如下:

size_t header_callback(char *buffer,   size_t size,   size_t nitems,   void *userdata);
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HEADERFUNCTION, header_callback);

当curl接收到 http header 时,该回调触发

2.1.14 CURLOPT_HEADERDATA

指定 CURLOPT_HEADERFUNCTION 调回的第4个参数

2.1.15 CURLOPT_RANGE

一般用于断点续传下载时设置数据传输传输范围。如:

curl_easy_setopt(curl, CURLOPT_RANGE,"100-");

表示需要获取服务器中 100 字节以后的数据

2.2 curl_slist_append

向 curl_slist* 中追加字符串内容。

struct curl_slist *curl_slist_append(struct curl_slist * list, const char * string );

如果第一个参数传 NULL 则返回一个新创建的curl_slist* . 与之对应的是 curl_slist_free_all()

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注