C++使用libcurl做HttpClient

2023-05-16

      当使用C++做HTTP客户端时,目前通用的做法就是使用libcurl。其官方网站的地址是http://curl.haxx.se/,该网站主要提供了Curl和libcurl。Curl是命令行工具,用于完成FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 以及 LDAP的命令的请求及接收回馈。libcurl提供给开发者,用于使用C++跨平台的开发各种网络协议的请求及响应。里面的文档非常齐全,不过都是英文的。

     本文提供最简单的demo使用libcurl开发HttpClient。主要包括同步的HTTP GET、HTTP POST、HTTPS GET、HTTPS POST。

    下载libcurl包,如果使用Linux平台,建议下载源文件编译;如果使用Windows平台,建议下载Win32 - MSVC,下载地址是:http://curl.haxx.se/download.html

#ifndef __HTTP_CURL_H__  
#define __HTTP_CURL_H__  
  
#include <string>  
  
class CHttpClient  
{  
public:  
    CHttpClient(void);  
    ~CHttpClient(void);  
  
public:  
    /** 
    * @brief HTTP POST请求 
    * @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com 
    * @param strPost 输入参数,使用如下格式para1=val1¶2=val2&… 
    * @param strResponse 输出参数,返回的内容 
    * @return 返回是否Post成功 
    */  
    int Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse);  
  
    /** 
    * @brief HTTP GET请求 
    * @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com 
    * @param strResponse 输出参数,返回的内容 
    * @return 返回是否Post成功 
    */  
    int Get(const std::string & strUrl, std::string & strResponse);  
  
    /** 
    * @brief HTTPS POST请求,无证书版本 
    * @param strUrl 输入参数,请求的Url地址,如:https://www.alipay.com 
    * @param strPost 输入参数,使用如下格式para1=val1¶2=val2&… 
    * @param strResponse 输出参数,返回的内容 
    * @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性. 
    * @return 返回是否Post成功 
    */  
    int Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath = NULL);  
  
    /** 
    * @brief HTTPS GET请求,无证书版本 
    * @param strUrl 输入参数,请求的Url地址,如:https://www.alipay.com 
    * @param strResponse 输出参数,返回的内容 
    * @param pCaPath 输入参数,为CA证书的路径.如果输入为NULL,则不验证服务器端证书的有效性. 
    * @return 返回是否Post成功 
    */  
    int Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath = NULL);  
  
public:  
    void SetDebug(bool bDebug);  
  
private:  
    bool m_bDebug;  
};  
  
#endif  
#include "httpclient.h"  
#include "curl/curl.h"  
#include <string>  
  
CHttpClient::CHttpClient(void) :   
m_bDebug(false)  
{  
  
}  
  
CHttpClient::~CHttpClient(void)  
{  
  
}  
  
static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *)  
{  
    if(itype == CURLINFO_TEXT)  
    {  
        //printf("[TEXT]%s\n", pData);  
    }  
    else if(itype == CURLINFO_HEADER_IN)  
    {  
        printf("[HEADER_IN]%s\n", pData);  
    }  
    else if(itype == CURLINFO_HEADER_OUT)  
    {  
        printf("[HEADER_OUT]%s\n", pData);  
    }  
    else if(itype == CURLINFO_DATA_IN)  
    {  
        printf("[DATA_IN]%s\n", pData);  
    }  
    else if(itype == CURLINFO_DATA_OUT)  
    {  
        printf("[DATA_OUT]%s\n", pData);  
    }  
    return 0;  
}  
  
static size_t OnWriteData(void* buffer, size_t size, size_t nmemb, void* lpVoid)  
{  
    std::string* str = dynamic_cast<std::string*>((std::string *)lpVoid);  
    if( NULL == str || NULL == buffer )  
    {  
        return -1;  
    }  
  
    char* pData = (char*)buffer;  
    str->append(pData, size * nmemb);  
    return nmemb;  
}  
  
int CHttpClient::Post(const std::string & strUrl, const std::string & strPost, std::string & strResponse)  
{  
    CURLcode res;  
    CURL* curl = curl_easy_init();  
    if(NULL == curl)  
    {  
        return CURLE_FAILED_INIT;  
    }  
    if(m_bDebug)  
    {  
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    }  
    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
    curl_easy_setopt(curl, CURLOPT_POST, 1);  
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());  
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);  
    res = curl_easy_perform(curl);  
    curl_easy_cleanup(curl);  
    return res;  
}  
  
int CHttpClient::Get(const std::string & strUrl, std::string & strResponse)  
{  
    CURLcode res;  
    CURL* curl = curl_easy_init();  
    if(NULL == curl)  
    {  
        return CURLE_FAILED_INIT;  
    }  
    if(m_bDebug)  
    {  
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    }  
<pre name="code" class="cpp">   curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  
    /** 
    * 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。 
    * 如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。 
    */  
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);  
    res = curl_easy_perform(curl);  
    curl_easy_cleanup(curl);  
    return res;  
}  
  
int CHttpClient::Posts(const std::string & strUrl, const std::string & strPost, std::string & strResponse, const char * pCaPath)  
{  
    CURLcode res;  
    CURL* curl = curl_easy_init();  
    if(NULL == curl)  
    {  
        return CURLE_FAILED_INIT;  
    }  
    if(m_bDebug)  
    {  
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    }  
    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
    curl_easy_setopt(curl, CURLOPT_POST, 1);  
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());  
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    if(NULL == pCaPath)  
    {  
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);  
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);  
    }  
    else  
    {  
        //缺省情况就是PEM,所以无需设置,另外支持DER  
        //curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");  
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);  
        curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);  
    }  
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);  
    res = curl_easy_perform(curl);  
    curl_easy_cleanup(curl);  
    return res;  
}  
  
int CHttpClient::Gets(const std::string & strUrl, std::string & strResponse, const char * pCaPath)  
{  
    CURLcode res;  
    CURL* curl = curl_easy_init();  
    if(NULL == curl)  
    {  
        return CURLE_FAILED_INIT;  
    }  
    if(m_bDebug)  
    {  
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);  
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);  
    }  
    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());  
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);  
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);  
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);  
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    if(NULL == pCaPath)  
    {  
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);  
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);  
    }  
    else  
    {  
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);  
        curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);  
    }  
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);  
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);  
    res = curl_easy_perform(curl);  
    curl_easy_cleanup(curl);  
    return res;  
}  
  
///  
  
void CHttpClient::SetDebug(bool bDebug)  
{  
    m_bDebug = bDebug;  
}  

参考:

https://www.yuque.com/docs/share/c0731a51-7f19-44e6-a312-70f815bd8f0e

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++使用libcurl做HttpClient 的相关文章

随机推荐

  • 一行代码解决selenium进入抖音出现验证滑块

    我正常从浏览器进入抖音是不出现验证滑块的 xff0c 然后用selenium进入抖音网站发现会出现滑块验证 如下如这是原代码 xff1a 运行代码后就会发现浏览器出现验证滑块 xff0c 这是是因为网站识别出你是使用selenium 这个时
  • 激光点云有关目标检测与目标跟踪的消息定义

    1 jsk recognition msgs BoundingBoxArray msg 安装jsk recognition msgs xff1a sudo apt get install ros melodic jsk recognitio
  • Linefit_ground_segmention文章梳理及代码阅读

    2013年专门针对地面分割的文章 xff1a Fast segmentation of 3D point clouds for ground vehicles 代码链接 xff1a https github com lorenwel lin
  • 使用MFC+GDI编写地图编辑器补充

    使用MFC 43 GDI编写地图编辑器补充 小宝乱猜 在编写MapEdit时我遇到一个问题 xff0c 那就是在程序开始时一切正常 xff0c 但在打开一个地图文件后 xff0c 程序就会因找不到资源文件而画面混乱 调试了半天才发现是相对路
  • 基于select模型的TCP服务器

    之前的一篇博文是基于TCP的服务器和客户机程序 xff0c 今天在这我要实现一个基于select模型的TCP服务器 xff08 仅实现了服务器 xff09 socket套接字编程提供了很多模型来使服务器高效的接受客户端的请求 xff0c s
  • 路由器端口介绍

    路由器所在的网络位置比较复杂 xff0c 既可是内部子网边缘 xff0c 也可位于内 外部网络边缘 同时为了实现强大的适用性 xff0c 它需要连接各种网络 xff0c 这样 xff0c 它的接口也就必须多种多样 对于这些 xff0c 不要
  • 光流(Optical Flow)

    光流的概念 光流是一种描述像素随时间在图像之间运动的方法 随着时间流逝 同一个像素会在图像中运动 我们希望追踪他的运动过程 稀疏光流 计算部分像素 稠密光流 计算全部像素 稀疏光流以Lucas Kanade光流为代表 简称LK光流 光流的两
  • 模块化程序 点与圆的关系 类中成员函数的声明和实现分开写入头文件和源文件中

    64 TOC 模块化程序 点和圆的关系 在黑马程序员课程4 1 3成员属性设置为私有 课后案例 点和圆的关系中 谈到了文件的封装 此案例是判断点与圆的关系 xff0c 重点是以另外一个类作为本类中的成员 xff1b 在比较大的开发中 xff
  • c++模板类/模板函数的声明与定义应该放在头文件里

    如果函数模板按照普通的函数声明放在头文件的 xff0c 定义放在 cpp文件 xff0c 会出现错误 xff1a 模板函数声明 定义 引用有什么要注意的问题么 xff1f xff1f mylib h template lt class T
  • checksum-8位和16位校验和代码示例

    span class hljs comment linux 系统编译通过 span span class hljs comment gcc filename c o filename span span class hljs comment
  • 安卓鉴权方式的总结

    HTTP Basic Authentication 这种授权方式是浏览器遵守http协议实现的基本授权方式 HTTP协议进行通信的过程中 xff0c HTTP协议定义了基本认证认证允许HTTP服务器对客户端进行用户身份证的方法 效果 xff
  • 手把手教你使用Vue搭建注册登录界面及前端源码

    文章目录 一 前言二 概况三 搭建注册页面四 改造登录页面四 整体效果动画演示五 前端源码下载六 后续 一 前言 本文将在vue admin template模板基础上完成搭建注册与登录页面 文末处有完整的前端源码下载 环境准备 浏览器 x
  • 从传感器和算法原理讲起,机器人是如何避障的

    导语 xff1a 本文内容来自大道智创CTO邢志伟在雷锋网硬创公开课的分享 xff0c 由雷锋网旗下栏目 新智造 整理 编者按 xff1a 本文内容来自大道智创CTO邢志伟在雷锋网 公众号 xff1a 雷锋网 硬创公开课的分享 xff0c
  • or1200处理器中的特殊寄存器

    以下内容摘自 步步惊芯 软核处理器内部设计分析 一书 OR1200中的寄存器分为两类 xff1a 通用寄存器r0 r31 特殊寄存器 特殊寄存器又分为11组 xff0c 在本书第1 3 3节简单地列出了所有的特殊寄存器组 从列表中可以发现除
  • 基础面试题 :大端、小端及转换方式

    理解网络中大端和小端往往是一道基础面试题 xff0c 这里作为记录和整理 xff0c 希望能帮到大家 目录 前言 一 字节序 二 什么小端顺序 三 什么大端顺序 四 处理器体系所属网络字节顺序 五 大小端转换 1 大端整形转换为小端 2 小
  • RS485——A与B波形与电路分析

    一 理论知识 发送端 AB间的电压差 xff0b 2 xff5e xff0b 6v 逻辑1 xff0d 2 xff5e xff0d 6v 逻辑0 xff1b 接收端 AB间的电压差 大于 xff0b 200mv 逻辑1 小于 xff0d 2
  • vsCode软件安装code runner插件,运行shell脚本,terminal终端不显示运行结果数据

    问题 vsCode软件安装code runner插件 xff0c 运行shell脚本 xff0c terminal终端不显示运行结果数据 原因分析 运行shell脚本 xff0c 没有指定运行的bash环境 解决办法 在Code runne
  • Microsoft Visual C++ Redistributable 与 Visual C++ 的区别与联系?

    Visual Studio xff1a 是一款开发软件 xff0c 即我们俗称的 IDE xff0c 有很多版本 xff0c 如 Visual Studio 2010 Visual C 43 43 xff1a Visual C 43 43
  • ROS下采用camera_calibration进行单目相机标定

    参考 xff1a https blog csdn net learning tortosie article details 79901255https blog csdn net learning tortosie article det
  • C++使用libcurl做HttpClient

    当使用C 43 43 做HTTP客户端时 xff0c 目前通用的做法就是使用libcurl 其官方网站的地址是http curl haxx se xff0c 该网站主要提供了Curl和libcurl Curl是命令行工具 xff0c 用于完