libCurl实现HTTP请求

2023-05-16

目录

  • 接口说明
    • 使用步骤
    • setopt函数部分选项说明
  • 示例
    • 写数据回调
    • GET请求
    • POST请求

libCurl是一个多协议、跨平台的客户端URL传输库;使用libCurl可方便地进行HTTP请求。

接口说明

libCurl提供easy interfacemulti interface两种HTTP请求方式;本文主要是easy interface的使用说明。

使用步骤

libCurl主要采用Callback方式完成数据传输,设置好参数后和回调函数后,在满足条件时会自动调用相应的回调函数实现对应功能。一般按如下顺序调用:

  • CURLcode curl_global_init(long flags):初始化库(只能调用一次),若在调用curl_easy_init时还未调用此函数,则libCurl库会自动调用此初始化函数。
  • CURL *curl_easy_init():初始化一个CURL指针(easy_handle对象,用于一系列easy函数中)。
  • CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter):设置传输选项(参数及回调函数);一般会多次调用。
  • CURLcode curl_easy_perform(CURL *handle):完成传输任务。
  • void curl_easy_cleanup(CURL *handle):清理释放
  • void curl_global_cleanup(void):清理库,在使用结束时调用。

setopt函数部分选项说明

curl所有设置都是在curl_easy_setopt中完成,其选项众多;部分常见选项:

  • CURLOPT_URL:设定请求的URL;
  • CURLOPT_HTTPHEADER:设定请求的HTTP头数据;
  • CURLOPT_POSTFIELDS,CURLOPT_POSTFIELDSIZE:POST请求时,设定发送的数据和长度。
  • CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA:设定如何处理接收到的数据,WRITEFUNCTION设定回调函数size_t callback(void *ptr, size_t size, size_t nmemb, void *stream),其中stream参数即为通过WRITEDATA设定的参数。
  • CURLOPT_HEADERFUNCTION,CURLOPT_HEADERDATA:设定如何处理接收到的HTTP头数据;
  • CURLOPT_VERBOSE:设定输出信息,当第三个参数为1时,会输出详细的操作信息(方便调试);
  • CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOU:设定传输与请求的超时时间,单位为秒;
  • CURLOPT_FOLLOWLOCATION,CURLOPT_MAXREDIRS:设定是否允许重定向(FOLLOWLOCATION非零时,会自动处理302错误),及最大重定向次数;

示例

以下是get与post请求的示例程序。

写数据回调

在有数据接收到时会被调用,size*nmemb是接收到的数据长度,userp是用户传递的接收数据的指针(示例中为string指针)。

static size_t http_curl_write_data(void *buffer, size_t size, size_t nmemb, void *userp) {
    if(NULL==userp || NULL==buffer || 0 == size)
        return 0;

    size_t realSize = size*nmemb;
    std::string *pstr = (std::string*)userp;
    if(NULL != pstr){
        pstr->append((const char*)buffer, realSize);
    }

    return realSize;
}

GET请求

请求的头信息通过map传入,返回接收到的response。

  • 请求头通过curl_slist_append组成一个链表后,作为参数传入;
  • CURLOPT_POST设为零;表示为GET请求;
  • 在perform请求成功后,还需通过curl_easy_getinfo获取对应的返回code,以判断请求是否真正成功。
string getRequest(const string &strUrl, const std::map<string, string> &mapHeader) {
    CURL *curl = curl_easy_init();
    if(NULL == curl){
        // ERROR:
        return "ERROR: call curl_easy_init fail";
    }

    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());

    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Content-Type: application/json");
    headers = curl_slist_append(headers, "charsets: utf-8");
    for(auto &h:mapHeader){
        headers = curl_slist_append(headers, buildHeader(h).c_str());
    }
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

    curl_easy_setopt(curl, CURLOPT_POST, 0); // GET request

    string strResp;
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&strResp);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_curl_write_data);

    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
    CURLcode res = curl_easy_perform(curl);
    bool bRet = false;
    if(res != CURLE_OK){ // connect fail
        // ERROR
        strResp = "ERROR: Connect fail: " + res;
    }
    else{
        long respCode;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &respCode);
        if(respCode == 200) {
            bRet = true; // success
        }
        else{
            // error-info in strResp
        }
    }

    curl_easy_cleanup(curl);
    curl_slist_free_all(headers);

    return strResp;
}

POST请求

发送的数据以JSON字符串参数的形式传入:

  • 默认即为POST请求,不需要做特殊设定;
  • 通过POSTFIELDS与POSTFIELDSIZE设定要发送的JSON数据;
string postRequest(string strUrl, string strJson) {
    CURL *curl = curl_easy_init();
    if(NULL == curl){
        // ERROR:
        return "ERROR: call curl_easy_init fail";
    }

    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());

    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Content-Type: application/json");
    headers = curl_slist_append(headers, "charsets: utf-8");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strJson.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strJson.length());

    string strResp;
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&strResp);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_curl_write_data);

    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
    CURLcode res = curl_easy_perform(curl);
    bool bRet = false;
    if(res != CURLE_OK){ // connect fail
        // ERROR
        strResp = "ERROR: Connect fail";
    }
    else{
        long respCode;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &respCode);
        if(respCode == 200) {
            bRet = true; // success
        }
        else{
            // error-info in strResp
        }
    }

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

libCurl实现HTTP请求 的相关文章

  • 如何防止 Firefox 缓存

    我尝试了很多可能的解决方案 但无法解决问题 这些不起作用 有人可以帮忙吗 我正在使用jsp servlet application 是websphere Portal 6 1 的一个portlet 切勿
  • 使用:text/plain; 有什么缺点吗?字符集=“UTF-8”

    我的网络服务器提供的内容在 95 的情况下只是简单的 ascii 但在极少数情况下 内容包含一些德语非 ASCII 字符 现在我可以设置content type通过检测内容是否包含任何非 ASCII 字符来响应标头 或者我可以始终设置响应标
  • 如何用 C 语言通过 HTTP 协议发送图像?

    我是一名正在做网络服务器练习的学生 我需要一些帮助 我的网络服务器在文本页面上运行良好 但是每当浏览器发送一个 GET img jpg HTTP 1 1请求 我不知道如何处理 我听说 HTTP 协议是基于文本的 那么如何在 HTTP 响应中
  • 为什么使用 Response 设置后,Request 中的 Cookie 立即可用?

    在页面加载中 如果您立即在下一行中执行 Response Cookies Add 您可以通过 Request Cookies 访问该 cookie 我知道在幕后 cookie 是由 net 添加到 Request Cookies 中的 但原
  • 当查看 X-Auth-Token 与 Authorization 标头之间的差异时,哪个是首选?

    下面两个标题有什么区别 哪一个是首选 X Auth Token dadas123sad12 Authorization Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ Authorization是客户端使用的主要标头认证如
  • Chrome 问题 - 视频流和会话冲突

    我在使用 javascript 和 PHP 实现视频时遇到问题 索引 php session start do other stuff include video php 视频 php
  • PHP 错误请求中 HTTP 请求失败

    我可以直接从浏览器请求 URL Web 服务 WS 但是当我在代码中使用 file get contents 或 fopen 方法时 我收到一条错误消息 有人有不使用curl的解决方案吗 public function sendHttpRe
  • 如何在PHP中完成http响应并进行进一步处理?

    就我而言 我需要向客户端回显一个标志并发送一封电子邮件 现在客户端需要等待电子邮件发送 但我想把这两个步骤分开 该怎么做呢 你可以看一下异步运行 PHP 任务 https stackoverflow com questions 858883
  • 在 Python 中发送 100,000 个 HTTP 请求的最快方法是什么?

    我正在打开一个包含 100 000 个 URL 的文件 我需要向每个 URL 发送 HTTP 请求并打印状态代码 我正在使用 Python 2 6 到目前为止 我已经了解了 Python 实现线程 并发的许多令人困惑的方式 我什至看过蟒蛇一
  • IFormFile 未由 dropzone uploadMultiple 请求填充

    我遇到的问题是 IFormFile 列表没有填充给定的文件 但是当我调用 HttpContext Request Form Files 时然后我就可以访问这些文件了 我更喜欢使用 IFormFile 因为它似乎是新的 Dotnet core
  • 从套接字读取 C HTTP

    我想知道如何判断是否已从套接字接收到所有数据 这是一个简单的网络代理 现在我正在处理请求部分 所以发送的内容应该以 r n r n 结尾 我不知道请求会持续多久 我在这里读过一些帖子 说我应该检查读取函数是否返回 0 但其他人说0只在客户端
  • 在 grails 中编写代理

    我正在使用 Gralis 1 3 7 我正在编写一个控制器 需要从另一台服务器获取 PDF 文件并将其返回给客户端 我想以某种相当有效的方式来做到这一点 例如 class DocController def view URL source
  • 如何知道 HTTP 服务器何时完成发送数据

    我正在开发一个面向浏览器 代理的项目 我需要下载网页 向 Web 服务器发送自定义 HTTP 请求后 我开始监听服务器响应 读取响应时 我检查响应标头中的 Content Length row 如果我得到其中之一 很容易确定服务器何时完成发
  • URL 哈希在重定向之间持续存在

    由于某种原因 当发送服务器端重定向 使用 Location 标头 时 非 IE 浏览器似乎会保留 URL 哈希 如果存在 例子 a simple redirect using Response Redirect http www yahoo
  • 如何在 Varnish 中禁用“传输编码:分块”编码?

    Using 清漆4 https www varnish cache org content varnish cache 400 我有一组后端以有效的方式响应Content Length标题和没有Transfer Encoding heade
  • 在 Go 中读取请求负载?

    我正在使用文件上传器 需要请求负载中的详细信息来裁剪它 func Upload w http ResponseWriter r http Request reader err r MultipartReader if err nil htt
  • 使用意图过滤器从 URL 打开 Android 应用程序不起作用

    我有一个 Android 应用程序 人们用它来替代网站 因此 当用户遇到网站的 URL 时 我想为他们提供在我的应用程序中而不是在浏览器中 打开 URL 的选项 换句话说 我希望出现弹出窗口 让他们在我的应用程序和浏览器 可能还有其他应用程
  • 从 Django 基于类的视图的 form_valid 方法调用特殊(非 HTTP)URL

    如果你这样做的话 有一个 HTML 技巧 a href New SMS Message a 点击新短信打开手机的本机短信应用程序并预 先填写To包含所提供号码的字段 在本例中为 1 408 555 1212 以及body与提供的消息 Hel
  • 如何给所有HttpClient请求方法添加参数?

    我正在编写一些使用 Apache 的 Java 代码HttpClient版本4 2 2使用 RESTful 第三方 API 该 API 具有利用 HTTP 的方法GET POST PUT and DELETE 需要注意的是 我使用的是 4
  • Java HttpURLConnection:内容长度计算

    我目前正在为 bitbucket issues RESTful API 开发一个库 我取得了很大的进步 现在我要解决这个部分更新问题 http confluence atlassian com display BBDEV Issues Is

随机推荐

  • 跑通VINS-Fusion全流程

    跑通VINS Fusion全流程 常规安装步骤详见官方1 ROS安装2 ceres solver安装3 VINS Fusion安装4 KITTI数据集下载5 跑通KITTI数据集 常规安装步骤详见官方 https github com HK
  • 带GPS的SLAM数据集汇总

    1 带GPS的相关SLAM数据集 Kitti 部分带部分不带 xff0c 看网站写的很详细 xff0c 数据集很常用 http www cvlibs net datasets kitti eval odometry php CMU Visu
  • 跑通GVINS——港科大新作

    跑通GVINS 港科大新作 0 简介1 环境2 跑通GVINS3 数据集4 相关资料打包下载 xff08 不包括数据集 xff09 6 泡泡机器人解读 港科大又一力作 xff01 vins mono以及vins fusion升级版GVINS
  • GVINS文章暴力翻译(仅供自学)

    GVINS文章暴力翻译 xff08 仅供自学 xff09 摘要1 介绍2 相关工作3 符号和定义A 框架b 状态 4 GNSS基本介绍A GNSS 概述B 伪距测量C 多普勒测量D SPP算法 5 系统概述6 概率公式A 地图估计B 惯性因
  • Vins-fusion用到的kitti数据集轨迹对不齐,使用evo -a转换

    kitti数据集基准问题 下面两个图一个是转换前 xff0c 一个是evo a 转换后的 问题描述 xff1a 现在遇到的问题是groundtruth和估计的位姿没有在一个坐标系中 xff0c 生成的轨迹对不齐 xff0c 需要首先根据位姿
  • 怎样用美图秀秀制作一寸照片

    有些时候 xff0c 老是会埋怨自己的http jingyan baidu com article 73c3ce28c852b7e50243d945 html证件照很难看 xff0c 自己拍的照片又不合格 xff0c 该怎么办呢 这里和大家
  • Realsense D435i关闭IR结构光

    Realsense D435i 关闭IR光 前言环境一次性关闭IR光从源码修改 前言 由于要做Realsense D435i的双目结构光相机标定 xff0c 其中用到了ROS来录制数据包 xff0c 但是结构光会影响标定 xff0c 所以得
  • vins-mono保存、重载地图、evo工具测试

    vins mono保存 重载地图 evo工具测试 地图保存与加载先跑起来修改地图保存的路径保存地图重载地图 evo测评evo工具修改数据格式使用evo绘制轨迹与双目ORB SLAM2进行对比 下面咱们来对vins mono地图进行简单测试
  • C++11新特性简介

    目录 功能扩展与增强 右值概念 类中右值扩展 标准库中右值扩展 内联命名空间 初始化 initialzier list 原始字符串 自定义字面值 类型自动推导 auto decltype 常量表达式函数constexpr 变长模板 空指针n
  • Realsense D435i单目跑ORB_SLAM2(无ROS版)

    主要参考mono euroc这个文件修改 xff0c 把数据源改成realsense的就可以了 如何获取realsense数据 xff0c 在之前的博客也阐述过 Realsense D435i 43 Opencv 获取彩色 深度 IMU数据
  • QGC开发 显示双GPS/RTK信息以及自定义页面(ubuntu)

    一 QGC开发 显示双GPS RTK信息 1 在sitl中进行仿真 xff0c 虚拟出第二个GPS mavlink发送到地面站 如下图中 xff0c 在mavlink msg gps2 raw h中找到发送第二组gps rtk数据函数mav
  • 03_FreeRTOS 二进制信号量

    03 FreeRTOS 二进制信号量 本文介绍 xff1a 二进制信号量的使用方法 简介信号量 信号量基本上用于将任务与系统中的其他事件同步 在FreeRTOS中 xff0c 信号量是基于队列机制实现的 FreeRTOS中有4种信号量 xf
  • 【首发】 ubuntu20.04安装matlab2021b/matlab2020b

    文章目录 一 下载地址1 1 2021b下载链接 BT 1 2 2021a下载链接1 3 2020b CSDN下载链接 二 MATLAB2021b安装方法2 1 Mount iso文件2 2 通过 install 启动安装程序2 3 输入正
  • 无人机右手定则以及角度大小方向粗判断

    无人机右手定则 xff1a 左力右场 xff0c 知道z轴方向 xff0c 然后就知道了xy轴方向 xff0c 其中x轴为大拇指指向的方向 四旋翼无人机欧拉角角度大小与其状态的关系 xff1a 设大地坐标系为 xff1a E xff08 O
  • NuttX RTOS

    目录 综述 NuttX是什么 看看这些文件和功能 它怎么会是一个小小的操作系统呢 xff1f NuttX讨论组 你想谈谈NuttX的特性吗 xff1f 你需要帮助吗 xff1f 问题吗 错误吗 下载 我在哪里可以买到NuttX xff1f
  • Arducopter Yaw角分析

    Arducopter Yaw 现梳理一遍Poshold模式下的yaw的情况 xff1a 首先从 Copter fast loop gt update flight mode gt Copter ModePosHold run span cl
  • TortoiseGit

    TortoiseGit用法 ubuntu16 04 18 04部署gitlab服务器 xff1a https blog csdn net qq 28263253 article details 80469203 一 如何安装 xff1a 下
  • 如何生成gazebo仿真环境的二维地图真值

    在移动机器人仿真中 xff0c 二维地图真值可以用来评价slam建图结果 xff0c 也可以直接给路径规划算法提供输入 利用gazebo进行仿真时 xff0c 有很多方法都可以获取静态仿真环境的二维地图真值 xff0c 本文将对以下链接 x
  • gazebo仿真环境加载模型方式

    我们都知道 xff0c gazebo可以在自带的gui中创建模型 导入模型 xff0c 然后将一批模型组成的仿真环境保存为一个world文件 xff1a 例如上图所示的场景 xff0c 我们可以从模型库中导入一些模型 xff0c 然后或直接
  • libCurl实现HTTP请求

    目录 接口说明使用步骤setopt函数部分选项说明 示例写数据回调GET请求POST请求 libCurl是一个多协议 跨平台的客户端URL传输库 xff1b 使用libCurl可方便地进行HTTP请求 接口说明 libCurl提供easy