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. 这些新项目一定不要错过「GitHub 热点速览」

    本周 GitHub 热点上榜的项目有不少的新面孔,比如搞电子商务的 eShop,还有处理表数据的 onetable.还有用来方便处理数据同步问题的 loro,以及网易新开源的 tts 项目 Emoti ...

  2. Python输入三个整数x,y,z,请把这三个数由小到大输出。

    break_out = False while 1: s = [] for i in range(3): x = int(input('请输入一个数:\n')) if x == -1: # 设计一个退 ...

  3. .net core下优秀的日志框架使用解析,附源代码

    在 .NET Core 中,日志是一个非常重要的组件,它可以帮助我们记录应用程序的运行情况,以便在出现问题时进行排查.在本文中,我们将介绍五个优秀的 .NET Core 日志框架,它们分别是 Seri ...

  4. 初始OpenGL

    OpenGL到底是什么? 一般它被认为是一个API,包含一系列操作图形,图像的函数.然而,它并不是一个API,而是Khronos组织制定并维护的规范. OpenGL规定了每个函数如何执行,以及它们的输 ...

  5. 深入 K8s 网络原理(二)- Service iptables 模式分析

    目录 1. 概述 2. 准备 Service 和 Pods 资源 3. K8s 里 Service 的实现原理 3.1 kube-proxy 组件 3.2 iptables 简介 3.3 iptabl ...

  6. 【UniApp】-uni-app-项目计算功能(苹果计算器)

    前言 本文主要介绍苹果计算器项目中计算功能的实现 在前面的文章中已经实现了输入,动态计算字体大小,以及计算器的布局 本文主要介绍计算功能的实现 正文 实现/清空/改变正负/除以100 inputTex ...

  7. 使用Mybatis自定义插件实现不侵入业务的公共参数自动追加

    背景 后台业务开发的过程中,往往会遇到这种场景:需要记录每条记录产生时间.修改时间.修改人及添加人,在查询时查询出来. 以往的做法通常是手动在每个业务逻辑里耦合上这么一块代码,也有更优雅一点的做法是写 ...

  8. jclasslib的安装

    双击安装包打开后点击下一步,然后选择安装的路径. 默认路径,如果c盘有空间不建议更改路径,然后再次点击下一步 依然选择下一步 最后点击完成即可完成安装.现在可以使用啦 注:如果需要安装包,请点击下面链 ...

  9. Java注解,看完就会用

    一.什么是注解 定义:注解(Annotation),也叫元数据.一种代码级别的说明. 它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次. 它可以声明在包.类.字段.方法.局部变 ...

  10. 从0开始学微信逆向开发(android版)——第一栏

    首先给大家普及一下啥叫微信逆向开发,以及微信逆向开发能做什么: 场景1:小明是做微商的,他每天需要加很多很多的好友.然后他会通过微信的各种渠道去添加好友,比如(附近的人.摇一摇.漂流瓶.手机号搜索等) ...