该要
本人主要使用libcurl进行http客户端代码的编写。Libcurl还支持众多的协议类型(ftp,imap,rtsp等),如果需要也可以查阅相关的文档。
Libcurl提供c语言的接口(无封装),因此需要注意释放申请的资源。同时该api的参数较多,我们只需要熟悉常见的参数即可,其它的等有需要时再进行查询。可能是灵活性方面的考虑,部分api使用回调函数函数的方式实现,同时需要用户自己完成回调函数的编写(暂不清楚是否有默认的回调函数提供)。
libcurl提供了两种接口,分别是easy interface和multi interface。easy interface以同步的方式进行数据传输,执行curl函数时会一直阻塞到数据传输完毕后返回,且一次操作只能发送一次请求,如果要同时发送多个请求,必须使用多线程。 而multi interface以一种简单的、非阻塞、异步的方式进行传输,它允许在一个线程中,同时提交多个相同类型的请求。
本文只介绍easy interface接口的使用。
接口介绍
初始化
CURL *curl = curl_easy_init(); //一旦实例化后需要通过下一个函数清理,否则会产生内存泄漏
curl_easy_cleanup(curl);
设置headers
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept:application/json"); // headers再赋值后也需要清理
headers = curl_slist_append(headers, "Content-Type:application/json");
headers = curl_slist_append(headers, "charsets:utf-8");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // 设置headers
curl_slist_free_all(headers); // 释放资源
设置请求类型
curl_easy_setopt(curl, CURLOPT_POST, 1) // post请求
curl_easy_setopt(curl, CURLOPT_GET, 1) // get请求
url设置
curl_easy_setopt(curl, CURLOPT_URL, url_.c_str());
超时设置
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, rw_timeout_ms_); // 读写超时
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, connect_timeout_ms_); // 连接超时
写body
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_para_str.c_str());
接收返回的headers
std::string resp_header;
curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void *)&resp_header); // 设置headers的载体
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, HeaderCallBack); //设置回调函数
static size_t HeaderCallBack(char *contents, size_t size, size_t nmemb, void *userp) {
std::string *result = reinterpret_cast<std::string*>(userp);
size_t num_char = size * nmemb;
reinterpret_cast<char*>(contents), num_char);
return num_char;
} // 该函数在接收headers的过程中可能多次被吊起,如果有一些特殊的需求,如统计写到读时间,可以加在该函数中
接收返回的body
std::string resp_body;
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&resp_body); // 设置body的载体
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, BodyCallBack); //设置回调函数
static int BodyCallBack(char *data, size_t size, size_t nmemb, std::string *buffer_in) {
if (NULL != buffer_in) {
buffer_in->append(data, size * nmemb);
return size * nmemb;
}
return 0;
} // 该函数同样可以被多次吊起,定制化开发
发送请求
curl_easy_perform(curl); // 正常情况返回值为CURLE_OK
参考文档
1、https://blog.youkuaiyun.com/MOU_IT/article/details/96457666