libcurl简介
- libcurl 是一个广泛使用的、支持多种协议的、开源的客户端url传输库,提供了许多用于数据传输的api,例如文件传输、ftp、http、https、smtp等。
- libcurl 的主要特点包括
- 支持多种协议:libcurl 支持多种协议,如 http、ftp、smtp 等,方便开发者在不同的场景下使用。
- 易于使用:libcurl 的 api 设计简洁,易于使用,方便开发者快速开发出网络通信功能。
- 可移植性强:libcurl 支持多种操作系统,如 linux、windows、macos 等,方便开发者在不同的平台上使用。
- 可定制性强:libcurl 支持插件机制,开发者可以根据自己的需求定制不同的插件,实现不同的功能。
- 高效稳定:libcurl 在数据传输过程中采用了多种优化技术,保证了数据传输的高效性和稳定性。
- 总的来说,libcurl 是一个功能强大、易于使用、可移植性强、可定制性强、高效稳定的网络通信库,被广泛应用于各种软件开发中。
- 本文章主要介绍libcurl在windows和linux平台下的编译步骤,并介绍了libcurl相关的api接口,最后通过一个demo演示如何通过libcurl发送http请求。
libcurl相关包下载
- libcurl github路径
- libcurl发行版本路径
- linux平台下载tar.gz包。以7.85.0版本为例,下载curl-7.85.0.tar.gz 包。
- windows平台下载zip包。 以7.85.0版本为例,下载curl-7.85.0.zip 包
- openssl发行版本 :使用libcurl一般都需要依赖openssl库
- openssl发行版本只有tar.gz包,windows/linux平台都使用这个包即可。以1.1.1u版本为例,下载 openssl-1.1.1u.tar.gz 包
- perl下载 : windows平台安装openssl需要这个工具
linux平台libcurl库编译
-
由于需要依赖openssl,先编译openssl库
-
openssl编译
- 解压openssl压缩包后进入解压后的目录
- 分别执行以下命令
-
./config --prefix=${pwd}/_install sudo make sudo make install
- 编译安装完成后,openssl相关库和头文件都会释放到 _install 目录下
-
libcurl编译
- 解压libcurl压缩包后进入解压后的目录
- 分别执行以下命令
-
./configure --prefix=${pwd}/_install --with-openssl=${pwd}/../openssl-1.1.1u/_install sudo make sudo make install
- –prefix 指定的是安装目录,如果不指定会默认安装到系统目录下。–with-openssl 指定的是openssl相关库目录。
- 编译安装完成后,相关库和头文件会释放到_install目录下
windows平台libcurl库编译
- 先安装perl,还需安装visual studio,建议使用 visual studio 2015
- 解压libcurl后进入目录
- 进入projects目录执行以下命令先编译openssl
-
build-openssl.bat vc14 -vspath "e:\program files (x86)\microsoft visual studio 14.0" x86 release ../../openssl-1.1.1u
- vspath指定的是 visual studio 2015 安装目录,如果默认安装在c盘,可不指定。最后指定openssl包的目录
- 编译完成后,会在openssl目录下的 build\win32\vc14 下生成openssl相关头文件和目录
-
- 进入libcurl目录下的 projects\windows\vc14 目录,使用 visual studio 2015 打开 curl-all.sln
- 解决方案将libcurl设为启动项目,这里选择编译32位,依赖openssl的release版本库
- 这里包含编译出来的openssl头文件目录
- 再链接编译出来的openssl动态库目录
- 保存编译后,在libcurl目录下的 build\win32\vc14\dll release - dll openssl 目录下就会生成对应的libcurl静态库和动态库。
相关接口
-
curlcode curl_global_init(long flags)
- 描述:初始化libcurl,只能调用一次,且在其他函数之前调用
- 参数
- flags
- curl_global_all : 初始化所有的可能的调用。
- curl_global_ssl : 初始化支持 安全套接字层。
- curl_global_win32 : 初始化win32套接字库。
- curl_global_nothing : 没有额外的初始化
- flags
- 返回值 : 返回 curle_ok 为成功,返回其他值失败
-
curl *curl_easy_init(void)
- 描述:初始化一个curl类型的指针,要在 curl_easy_cleanup 中进行释放。
- 返回值: 返回一个 curl 类型指针,在 curl_easy_setopt 函数中使用
-
curlcode curl_easy_setopt(curl *curl, curloption option, …);
- 描述:设置选项
- 参数
- curl : curl_easy_init 返回的 curl类型指针
- option :curl_easy_setopt函数option参数介绍
- 返回值 : 返回 curle_ok 为成功,返回其他值失败
-
curlcode curl_easy_perform(curl *curl)
- 描述:以阻塞方式执行请求
- 参数:
- curl :curl_easy_init 返回的 curl类型指针
- 返回值:返回 curle_ok 为成功,返回其他值失败
-
curlcode curl_easy_getinfo(curl *curl, curlinfo info, …)
- 描述:请求curl 会话中的相关信息
- 参数
- curl :curl_easy_init 返回的 curl类型指针
- info
- curlinfo_response_code :获取http状态码
- 其他参数描述
- 返回值:返回 curle_ok 为成功,返回其他值失败
-
void curl_easy_reset(curl *curl)
- 描述:重新初始化curl指针为默认值
-
void curl_easy_cleanup(curl *curl)
- 描述:清理 curl_easy_init 接口申请的 curl 类型指针
-
curl_easy_setopt函数option参数介绍
- curlopt_url :设置要访问的url
- curlopt_writefunction :设置回调函数,回调函数在libcurl接收到数据后被调用
- 回调函数原型:size_t function(void *ptr, size_t size, size_t nmemb, void *stream);
- curlopt_writedata :用于表明 curlopt_writefunction 函数中的stream指针的来源
- curlopt_headerfunction :设置回调函数,回调函数在libcurl接收到http响应头后被调用
- 回调函数原型 : size_t function( void *ptr, size_t size,size_t nmemb, void *stream);
- curlopt_headerdata : 表明curlopt_headerfunction 函数的stream指针的来源。
- curlopt_timeout :设置数据传输超时时间
- curlopt_connectiontimeout :设置连接超时时间
- curlopt_post :设置请求方式为post
- curlopt_postfields : 设置post请求体
- curlopt_postfieldsize :设置post请求大小
- curlopt_httpheader : 设置http请求头
- curlopt_ssl_verifypeer :设置是否验证对端证书,设置为0表示不验证。默认为1,表示验证。
- curlopt_ssl_verifyhost :设置是都验证服务器证书,设置为0表示不验证。
- 其他参数
演示代码
- 本测试代码通过libcurl实现发送http请求
-
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <curl/curl.h> #include <iostream> typedef struct { std::string body; size_t bodysize; } stresponse; typedef struct { std::string header; size_t headersize; } stresponseheader; size_t responsebodycallback(void *ptr, size_t size, size_t nmemb, void *stream) { stresponse* presponse = (stresponse*)stream; presponse->body.append((char*)ptr, size * nmemb); presponse->bodysize = size * nmemb; return size * nmemb; } size_t responseheadercallback(void *ptr, size_t size, size_t nmemb, void *stream){ stresponseheader* presponseheader = (stresponseheader*)stream; presponseheader->header.append((char*)ptr, size * nmemb); presponseheader->headersize = size * nmemb; return size * nmemb; } int main(){ std::string readbuffer; stresponse response; stresponseheader responseheader; // 初始化所有可能的调用 curl_global_init(curl_global_all); curl *curl = curl_easy_init(); // 设置url curl_easy_setopt(curl, curlopt_url, "http://182.92.205.179:10088"); // 设置post请求,不设置或设置为0则为get请求 curl_easy_setopt(curl, curlopt_post, 1); // 设置post请求体 char postdata[1024] = "{\"req\":\"hello\"}"; curl_easy_setopt(curl, curlopt_postfields, postdata); // 设置post请求体大小 curl_easy_setopt(curl, curlopt_postfieldsize, strlen(postdata)); // 设置http请求头 curl_slist* headerlist = null; headerlist = curl_slist_append(headerlist, "content-type: application/json"); headerlist = curl_slist_append(headerlist, "flag: libcurl"); curl_easy_setopt(curl, curlopt_httpheader, headerlist); // 设置不校验证书,https请求时使用 curl_easy_setopt(curl, curlopt_ssl_verifypeer, 0); curl_easy_setopt(curl, curlopt_ssl_verifyhost, 0); // 设置回调函数获取响应体数据 curl_easy_setopt(curl, curlopt_writefunction, responsebodycallback); curl_easy_setopt(curl, curlopt_writedata, (void*)&response); // 设置回调函数获取响应头数据 curl_easy_setopt(curl, curlopt_headerfunction, responseheadercallback); curl_easy_setopt(curl, curlopt_headerdata, (void*)&responseheader); // 超时时间 curl_easy_setopt(curl, curlopt_timeout, 5); // 执行请求 curlcode res = curl_easy_perform(curl); // 检查错误 if(res == curle_ok){ // 获取状态码 int responsecode = 0; curl_easy_getinfo(curl, curlinfo_response_code, &responsecode); std::cout << "code : "<<responsecode << std::endl; std::cout << "responseheader size : "<<responseheader.headersize << std::endl; std::cout << "responseheader header : "<<responseheader.header.c_str() << std::endl; std::cout << "response size : "<<response.bodysize << std::endl; std::cout << "response body : "<<response.body.c_str() << std::endl; }else{ std::cout<<curl_easy_strerror(res)<<std::endl; } curl_slist_free_all(headerlist); // 清理 curl_easy_cleanup(curl); return 0; }
- 完整工程已上传至gitee 测试工程
发表评论