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. 决策树C4.5算法的技术深度剖析、实战解读

    在本篇深入探讨的文章中,我们全面分析了C4.5决策树算法,包括其核心原理.实现流程.实战案例,以及与其他流行决策树算法(如ID3.CART和Random Forests)的比较.文章不仅涵盖了丰富的理 ...

  2. 每天5分钟复习OpenStack(十)Ceph 架构

    在很多关于Ceph的文章中,通常会介绍一堆概念.虽然这些概念很重要,但是对于一个新手来说,同时接受太多的概念实际上很难消化.因此,在阅读本章节时要保持轻松的心情,只需要对所有的概念有个了解就可以了,因 ...

  3. 大数据分析/机器学习基础之matplotlib绘图篇

    目录 一.前言 我的运行环境 二.什么是matplotlib? 三.安装及导入 四.matplotlib的使用 一.前言 本人因在学习基于python的机器学习相关教程时第一次接触到matplotli ...

  4. Snipaste安装与使用教程

    一.下载 1.官网 下载地址 2.下载 可以直接在官网下载,也可以跳转微软仓库下载增强版的.如果是其他系统,mac在最下面,而Linux现在没有需要等待. 二.开始安装 1.下载完毕,是一压缩包绿色版 ...

  5. Java实现相似结构表算法

    [产品需求] 对所有元数据进行分析,匹配出表字段相似度达到阈值的向相似结构表关系数据. 网上没有搜到相关算法实现,只能自己动手了. [算法实现] 简单点实现的话,可以轮询所有表,每张表都和其它表进行匹 ...

  6. Java并发(十七)----变量的线程安全分析

    1.成员变量和静态变量是否线程安全 如果它们没有共享,则线程安全 如果它们被共享了,根据它们的状态是否能够改变,又分两种情况 如果只有读操作,则线程安全 如果有读写操作,则这段代码是临界区,需要考虑线 ...

  7. SpringBoot设置日志级别

    输出到控制台 logging: # 日志记录到文件中 file: # 指定文件名 name: server.log logback: rollingpolicy: # 指定文件大小 max-file- ...

  8. ElasticSearch-Mapping类型映射-增删改查

    https://www.elastic.co/guide/en/elasticsearch/reference/6.8/mapping.html 7.x版本后默认都是_doc类型 增加Mapping映 ...

  9. 【JVM】一文掌握JVM垃圾回收机制

    作为Java程序员,除了业务逻辑以外,随着更深入的了解,都无法避免的会接触到JVM以及垃圾回收相关知识.JVM调优是一个听起来很可怕,实际上很简单的事. 感到可怕,是因为垃圾回收相关机制都在JVM的C ...

  10. 云MSP技本功|基于OGG 实现Oracle到Kafka增量数据实时同步

    简介: 在大数据时代,存在大量基于数据的业务.数据需要在不同的系统之间流动.整合.通常,核心业务系统的数据存在OLTP数据库系统中,其它业务系统需要获取OLTP系统中的数据.传统的数仓通过批量数据同步 ...