libcurl简介

libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证

libcurl的官网: http://curl.haxx.se/

库下载地址: https://github.com/curl/curl/releases/tag/curl-7_71_1

libcurl的简单使用

初始化libcurl:

curl_global_init()

函数得到 easy interface型指针:

curl_easy_init()

设置传输选项:

curl_easy_setopt()

设置的传输选项,实现回调函数以完成用户特定任务:

curl_easy_setopt()

函数完成传输任务:

curl_easy_perform()

释放内存:

curl_easy_cleanup()

curl_global_init

CURLcode curl_global_init(long flags);函数只能用一次。(其实在调用curl_global_cleanup 函数后仍然可再用)

如果这个函数在curl_easy_init函数调用时还没调用,它讲由libcurl库自动调用,

所以多线程下最好主动调用该函数以防止在线程中curl_easy_init时多次调用。

注意:虽然libcurl是线程安全的,但curl_global_init是不能保证线程安全的,

所以不要在每个线程中都调用curl_global_init,应该将该函数的调用放在主线程中。

写入此函数避免出现上述风险:

  • 参数:flags

    CURL_GLOBAL_ALL //初始化所有的可能的调用。
    CURL_GLOBAL_SSL //初始化支持 安全套接字层。
    CURL_GLOBAL_WIN32 //初始化win32套接字库。
    CURL_GLOBAL_NOTHING //没有额外的初始化。

封装:C++使用libcurl实现HTTP POST和GET

在C++中使用libcurl实现HTTP POST和GET的源码如下:

#include <curl/curl.h>
#include <string> class HttpConnection {
public:
HttpConnection() {
curl_global_init(CURL_GLOBAL_ALL);
curl_ = curl_easy_init();
} ~HttpConnection() {
curl_easy_cleanup(curl_);
} bool Post(const std::string& url, const std::string& data, std::string& response) {
if (!curl_) {
return false;
} // set params
// set curl header
struct curl_slist* header_list = NULL;
// der_list = curl_slist_append(header_list, "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko");
header_list = curl_slist_append(header_list, "Content-Type:application/json; charset = UTF-8");
curl_easy_setopt(curl_, CURLOPT_HTTPHEADER, header_list); curl_easy_setopt(curl_, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl_, CURLOPT_POST, 1L);
curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, data.c_str());
curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, &WriteCallback);
curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &response); CURLcode res = curl_easy_perform(curl_);
return (res == CURLE_OK);
} bool Get(const std::string& url, std::string& response) {
if (!curl_) {
return false;
} curl_easy_setopt(curl_, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl_, CURLOPT_POST, 0L);
curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, &WriteCallback);
curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &response); CURLcode res = curl_easy_perform(curl_);
return (res == CURLE_OK);
} private:
CURL* curl_ = nullptr; static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
size_t realsize = size * nmemb;
std::string* str = static_cast<std::string*>(userp);
str->append(static_cast<char*>(contents), realsize);
return realsize;
}
};

这个类中包含了两个公共方法Post和Get,用于实现HTTP的POST和GET请求。

它们接受一个URL参数和可选的请求数据,以及一个用于存储响应的字符串引用。

在使用这个类之前,需要先创建一个实例,并调用Post或Get方法。

如果请求成功,方法会返回true,并将服务器响应存储在传递的response字符串中。

否则,它将返回false,response将保持为空字符串。

扩展,LibCurl 实现 Put 操作

#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h> #include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <check_error.h> FILE *fp; //定义FILE类型指针 //重写把数据读入上传数据流函数
size_t read_file(void* buff, size_t size, size_t nmemb, void* userp)
{
size_t sizes = fread(buff, size, nmemb, (FILE *)userp);
return sizes;
} int main(int argc,char **argv)
{
CURLcode res; //easy_handle定义的一些错误码
const char url[2096];
//初始化libcurl if(argc!=3)
{
printf("please input url and filename");
exit(-1);
}
res = curl_global_init(CURL_GLOBAL_ALL);
if (res != CURLE_OK)
{
printf("init libcurl failed.\n" );
return -1;
} //获取要上传的文件指针
FILE* r_file = fopen(argv[2], "rb");
if (0 == r_file)
{
printf( "the file %s isnot exit\n",argv[2]);
return -1;
} CURL* easy_handle; easy_handle = curl_easy_init();
if (0 == easy_handle)
{
printf( "get a easy_handle handle fail!");
fclose(r_file);
curl_global_cleanup();
curl_easy_cleanup(easy_handle);
return -1;
} // 获取文件大小
fseek(r_file, 0, 2);
int file_size = ftell(r_file);
rewind(r_file); curl_easy_setopt(easy_handle, CURLOPT_URL, argv[1]); //获取URL地址
curl_easy_setopt(easy_handle, CURLOPT_UPLOAD, 1); //告诉easy_handle是做上传操作
curl_easy_setopt(easy_handle, CURLOPT_READFUNCTION, &read_file); //调用重写的读文件流函数
curl_easy_setopt(easy_handle, CURLOPT_READDATA, r_file); //往read_file()函数中传入用户自定义的数据类型
curl_easy_setopt(easy_handle, CURLOPT_INFILE, r_file); //定位作为上传的输入文件
curl_easy_setopt(easy_handle, CURLOPT_VERBOSE, 1); //打印出具体http协议字段
//curl_easy_setopt(easy_handle, CURLOPT_HEADER, 1);
curl_easy_setopt(easy_handle, CURLOPT_INFILESIZE, file_size); //上传的字节数 //执行设置好的操作
res = curl_easy_perform(easy_handle); //获取HTTP错误码
int HTTP_flag = 0;
curl_easy_getinfo(easy_handle, CURLINFO_RESPONSE_CODE , &HTTP_flag); //一般清理动作
fclose(r_file);
curl_global_cleanup();
curl_easy_cleanup(easy_handle); printf("url :%s localfile: %s\n",argv[1],argv[2]);
printf("HTTP_flag is %d\n",HTTP_flag); // printf( "操作本地文件: file_name url:\n");
//检测HTTP错误码和执行操作结果
if (CURLE_OK != res)
{
printf("failure\n");
return -1;
}
else
{
printf("success\n");
return 0;
}
}

在 StackOverFlow 中有一则关于 Put 操作的问题:https://stackoverflow.com/questions/7569826/send-string-in-put-request-with-libcurl

其中的回答有说:Dont use curl_easy_setopt(curl, CURLOPT_PUT, 1L);

比较好的写法是如此:

curl = curl_easy_init();

if (curl) {
headers = curl_slist_append(headers, client_id_header);
headers = curl_slist_append(headers, "Content-Type: application/json"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, request_url);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); /* !!! */ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_struct); /* data goes here */ res = curl_easy_perform(curl); curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}

比较好奇 why 这样,结果查询 LibCurl 官方的资料说:CURLOPT_PUT 已经被弃用了(简单明了,所以正确的使用姿势应该保证是 CURLOPT_UPLOAD Option)

【LibCurl】C++使用libcurl实现HTTP POST和GET、PUT的更多相关文章

  1. libCURL开源库在VS2010环境下编译安装,配置详解

    libCURL开源库在VS2010环境下编译安装,配置详解 转自:http://my.oschina.net/u/1420791/blog/198247 http://blog.csdn.net/su ...

  2. libcurl安装使用方法-简单实用(摘录)

    http://curl.haxx.se/libcurl/c/example.html 官网c例子http://curl.haxx.se/download/curl-7.21.3.tar.gz 下载地址 ...

  3. linux c libcurl的简单使用(转)

    curl是Linux下一个非常著名的下载库,通过这个库,可以很简单的实现文件的下载等操作.看一个简单的例子: #include <curl/curl.h> #include <std ...

  4. Libcurl笔记二

    一: multi与easy接口的不同处The multi interface offers several abilities that the easy interface doesn't. The ...

  5. 如何编译libcurl

    1. Android •1.1配置 •1.2 Make •1.3的参数配置 2.iOS 3.windows 4.关于头文件 注释 本文档介绍了如何为Android,iOS和Windows编译libcu ...

  6. libcurl的封装,支持同步异步请求,支持多线程下载,支持https

    最近在做一个项目,需要用到http get post等 需求分析需要做到同步和异步,异步请求的返回以可选的回调通知的方式进行. 本人以Linux为例,一步一步的来实现. 配置并且编译libcurl我以 ...

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

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

  8. Libcurl最初的实现tfp上传和下载功能

    研究报告指出的目标是使用libcurl实现ftp文件上传和下载功能 一.Libcurlde简要 Libcurl的而且易于使用的利用url进行文件传输的库. , libcurl当前支持DICT, FIL ...

  9. Libcurl细说

    libcurl教程   原文地址:http://curl.haxx.se/libcurl/c/libcurl-tutorial.html 译者:JGood(http://blog.csdn.net/J ...

  10. 最全的libcurl库资源整理

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

随机推荐

  1. 在 Sealos 中使用区块链技术实现统一支付系统

    拿着区块链技术不一定是去发币,很多业务系统也适合用这些技术,比如做个统一支付系统,积分系统等,可以做为一家公司的金融基础设施,或支付中台.拿链的技术去做有很多好处: 高可用,自带多区域高一致性的能力, ...

  2. 接手了个项目,被if..else搞懵逼了

    背景 领导:"这个项目,今后就给你维护了啊,仔细点." 小猫:"好,没问题". 可当满怀信心的小猫打开项目工程包翻看一些代码之后,瞬间懵逼没了信心. 是这样的 ...

  3. 数字孪生与VR设备的融合为旅游行业带来革新

    数字时代的推动下,旅游行业正迎来一场革命性的变革.数字孪生系统与虚拟现实(VR)的融合为旅游体验带来了全新的可能性.通过数字孪生技术的实时模拟和VR设备的沉浸式体验,旅游行业迎来了全新的变革时代. 数 ...

  4. ImportError: No module named pypinyin

    import platform, subprocess, os, zipfile, xml, re, pypinyin ImportError: No module named pypinyin pi ...

  5. 技本功|Hive优化之监控(三)

    Hive是大数据领域常用的组件之一,主要是大数据离线数仓的运算,关于Hive的性能调优在日常工作和面试中是经常涉及的一个点,因此掌握一些Hive调优是必不可少的技能.影响Hive效率的主要有数据倾斜. ...

  6. Havoc插件编写

    ‍ 配置文件的webhook支持discord,所以尝试使用钉钉和企业微信. WebHook { Discord { Url = "" AvatarUrl = "&quo ...

  7. 五菱宝骏车机升级教程【嘟嘟桌面或ES文件管理器】

    文章来源:https://www.djww.net/607.html 简介 越来越多的汽车厂商自研车机系统,其实就是在原来安卓的基础上加入自己的元素,然后禁用某些功能从而实现禁止用户安装第三方app. ...

  8. 深入了解RC4 Drop加密技术

    一.引言 在网络安全领域,加密技术始终是重中之重.随着计算机技术的发展,加密算法也在不断更新换代.RC4(Rivest Cipher 4)加密算法因其高效.简洁的特性,在信息安全领域得到了广泛的应用. ...

  9. 介绍3种ssh远程连接的方式

    摘要:SSH(安全外壳协议 Secure Shell Protocol,简称SSH)是一种加密的网络传输协议,用于在网络中实现客户端和服务端的连接,典型的如我们在本地电脑通过 SSH连接远程服务器. ...

  10. 论文解读丨CIKM'22 MARINA:An MLP-Attention Model for Multivariate Time-Series Analysis

    摘要:华为云数据库创新Lab在论文<MARINA: An MLP-Attention Model for Multivariate Time-Series Analysis>中提出了华为自 ...