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 的一般流程:
- curl_global_init() 进行库的初始化
- curl_easy_init() 获取CURL* 指针
- curl_easy_setopt() 设置传输参数,包括回调等
- curl_easy_perform() 完成传输
- curl_easy_cleanup() 释放内存
- curl_global_cleanup() 释放库内存
我们需要着重关心的,是第 3 步。在这一步里,我们将指定 libcurl 如何将参数传递给服务端。
1.1 简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#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 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/* 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
对返回的数据进行操作的函数指针 回调函数的原型为:
1 2 |
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 的回调函数指针。回调函数原型如下:
1 2 |
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
一般用于断点续传下载时设置数据传输传输范围。如:
1 |
curl_easy_setopt(curl, CURLOPT_RANGE,"100-"); |
表示需要获取服务器中 100 字节以后的数据
2.2 curl_slist_append
向 curl_slist* 中追加字符串内容。
1 |
struct curl_slist *curl_slist_append(struct curl_slist * list, const char * string ); |
如果第一个参数传 NULL 则返回一个新创建的curl_slist* . 与之对应的是 curl_slist_free_all()