libcurl开源库的编译与使用全攻略

news2024/11/19 14:32:32

libcurl简介

  • libcurl 是一个广泛使用的、支持多种协议的、开源的客户端URL传输库,提供了许多用于数据传输的API,例如文件传输、FTP、HTTP、HTTPS、SMTP等。
  • libcurl 的主要特点包括
    • 支持多种协议:libcurl 支持多种协议,如 HTTP、FTP、SMTP 等,方便开发者在不同的场景下使用。
    • 易于使用:libcurl 的 API 设计简洁,易于使用,方便开发者快速开发出网络通信功能。
    • 可移植性强:libcurl 支持多种操作系统,如 Linux、Windows、MacOS 等,方便开发者在不同的平台上使用。
    • 可定制性强:libcurl 支持插件机制,开发者可以根据自己的需求定制不同的插件,实现不同的功能。
    • 高效稳定:libcurl 在数据传输过程中采用了多种优化技术,保证了数据传输的高效性和稳定性。
  • 总的来说,libcurl 是一个功能强大、易于使用、可移植性强、可定制性强、高效稳定的网络通信库,被广泛应用于各种软件开发中。
  • 本文章主要介绍libcurl在windows和linux平台下的编译步骤,并介绍了libcurl相关的API接口,最后通过一个demo演示如何通过libcurl发送http请求。

libcurl相关包下载

  • libcurl github路径
  • libcurl发行版本路径
    • linux平台下载tar.gz包。以7.85.0版本为例,下载curl-7.85.0.tar.gz 包。
    • windows平台下载zip包。 以7.85.0版本为例,下载curl-7.85.0.zip 包
  • openssl发行版本 :使用libcurl一般都需要依赖openssl库
    • openssl发行版本只有tar.gz包,windows/linux平台都使用这个包即可。以1.1.1u版本为例,下载 openssl-1.1.1u.tar.gz 包
  • perl下载 : windows平台安装openssl需要这个工具

linux平台libcurl库编译

  • 由于需要依赖openssl,先编译openssl库

  • openssl编译

    • 解压openssl压缩包后进入解压后的目录
    • 分别执行以下命令
    •   ./config --prefix=${PWD}/_install
        sudo make
        sudo make install
      
    • 编译安装完成后,openssl相关库和头文件都会释放到 _install 目录下
  • libcurl编译

    • 解压libcurl压缩包后进入解压后的目录
    • 分别执行以下命令
    •   ./configure --prefix=${PWD}/_install --with-openssl=${PWD}/../openssl-1.1.1u/_install
        sudo make 
        sudo make install
      
    • –prefix 指定的是安装目录,如果不指定会默认安装到系统目录下。–with-openssl 指定的是openssl相关库目录。
    • 编译安装完成后,相关库和头文件会释放到_install目录下

windows平台libcurl库编译

  • 先安装perl,还需安装Visual Studio,建议使用 Visual Studio 2015
  • 解压libcurl后进入目录
  • 进入projects目录执行以下命令先编译openssl
    •   build-openssl.bat vc14 -VSpath "E:\Program Files (x86)\Microsoft Visual Studio 14.0" x86 release ../../openssl-1.1.1u
      
    • VSpath指定的是 Visual Studio 2015 安装目录,如果默认安装在C盘,可不指定。最后指定openssl包的目录
    • 编译完成后,会在openssl目录下的 Win32\VC14 下生成openssl相关头文件和目录
  • 进入libcurl目录下的 projects\Windows\VC14 目录,使用 Visual Studio 2015 打开 curl-all.sln
  • 解决方案将libcurl设为启动项目,这里选择编译32位,依赖openssl的Release版本库 在这里插入图片描述
  • 这里包含编译出来的openssl头文件目录
    在这里插入图片描述
  • 再链接编译出来的openssl动态库目录
    在这里插入图片描述
  • 保存编译后,在libcurl目录下的 build\Win32\VC14\DLL Release - DLL OpenSSL 目录下就会生成对应的libcurl静态库和动态库。
    在这里插入图片描述

相关接口

  • CURLcode curl_global_init(long flags)

    • 描述:初始化libcurl,只能调用一次,且在其他函数之前调用
    • 参数
      • flags
        • CURL_GLOBAL_ALL : 初始化所有的可能的调用。
        • CURL_GLOBAL_SSL : 初始化支持 安全套接字层。
        • CURL_GLOBAL_WIN32 : 初始化win32套接字库。
        • CURL_GLOBAL_NOTHING : 没有额外的初始化
    • 返回值 : 返回 CURLE_OK 为成功,返回其他值失败
  • CURL *curl_easy_init(void)

    • 描述:初始化一个CURL类型的指针,要在 curl_easy_cleanup 中进行释放。
    • 返回值: 返回一个 CURL 类型指针,在 curl_easy_setopt 函数中使用
  • CURLcode curl_easy_setopt(CURL *curl, CURLoption option, …);

    • 描述:设置选项
    • 参数
      • curl : curl_easy_init 返回的 CURL类型指针
      • option :curl_easy_setopt函数option参数介绍
    • 返回值 : 返回 CURLE_OK 为成功,返回其他值失败
  • CURLcode curl_easy_perform(CURL *curl)

    • 描述:以阻塞方式执行请求
    • 参数
      • curl :curl_easy_init 返回的 CURL类型指针
    • 返回值:返回 CURLE_OK 为成功,返回其他值失败
  • CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, …)

    • 描述:请求curl 会话中的相关信息
    • 参数
      • curl :curl_easy_init 返回的 CURL类型指针
      • info
        • CURLINFO_RESPONSE_CODE :获取http状态码
        • 其他参数描述
    • 返回值:返回 CURLE_OK 为成功,返回其他值失败
  • void curl_easy_reset(CURL *curl)

    • 描述:重新初始化CURL指针为默认值
  • void curl_easy_cleanup(CURL *curl)

    • 描述:清理 curl_easy_init 接口申请的 CURL 类型指针
  • curl_easy_setopt函数option参数介绍

    • CURLOPT_URL :设置要访问的URl
    • CURLOPT_WRITEFUNCTION :设置回调函数,回调函数在libcurl接收到数据后被调用
      • 回调函数原型:size_t function(void *ptr, size_t size, size_t nmemb, void *stream);
    • CURLOPT_WRITEDATA :用于表明 CURLOPT_WRITEFUNCTION 函数中的stream指针的来源
    • CURLOPT_HEADERFUNCTION :设置回调函数,回调函数在libcurl接收到http响应头后被调用
      • 回调函数原型 : size_t function( void *ptr, size_t size,size_t nmemb, void *stream);
    • CURLOPT_HEADERDATA : 表明CURLOPT_HEADERFUNCTION 函数的stream指针的来源。
    • CURLOPT_TIMEOUT :设置数据传输超时时间
    • CURLOPT_CONNECTIONTIMEOUT :设置连接超时时间
    • CURLOPT_POST :设置请求方式为post
    • CURLOPT_POSTFIELDS : 设置post请求体
    • CURLOPT_POSTFIELDSIZE :设置post请求大小
    • CURLOPT_HTTPHEADER : 设置http请求头
    • CURLOPT_SSL_VERIFYPEER :设置是否验证对端证书,设置为0表示不验证。默认为1,表示验证。
    • CURLOPT_SSL_VERIFYHOST :设置是都验证服务器证书,设置为0表示不验证。
    • 其他参数

演示代码

  • 本测试代码通过libcurl实现发送http请求
  •   #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <curl/curl.h>
      #include <iostream>
      
      typedef struct {
          std::string body;
      	size_t bodySize;
      } stResponse;
      
      typedef struct {
          std::string header;
      	size_t headerSize;
      } stResponseHeader;
      
      size_t responseBodyCallback(void *ptr, size_t size, size_t nmemb, void *stream) {
          stResponse* pResponse = (stResponse*)stream;
      	pResponse->body.append((char*)ptr, size * nmemb);
      	pResponse->bodySize = size * nmemb;
      	return size * nmemb;
      }
      
      size_t responseHeaderCallback(void *ptr, size_t size, size_t nmemb, void *stream){
      	stResponseHeader* pResponseHeader = (stResponseHeader*)stream;
      	pResponseHeader->header.append((char*)ptr, size * nmemb);
      	pResponseHeader->headerSize = size * nmemb;
      	return size * nmemb;
      }
      
      int main(){
      	std::string readBuffer;
      	stResponse response;
      	stResponseHeader responseHeader;
      
      	// 初始化所有可能的调用
      	curl_global_init(CURL_GLOBAL_ALL);
      
      	
      	CURL *curl = curl_easy_init();
      
      	// 设置url
      	curl_easy_setopt(curl, CURLOPT_URL, "http://182.92.205.179:10088");
      
      	// 设置post请求,不设置或设置为0则为get请求
      	curl_easy_setopt(curl, CURLOPT_POST, 1);
      	// 设置post请求体
      	char postData[1024] = "{\"req\":\"hello\"}";
      	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
      	// 设置post请求体大小
      	curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(postData));
      
      	// 设置http请求头
      	curl_slist* headerList = NULL;
      	headerList = curl_slist_append(headerList, "Content-Type: application/json");
      	headerList = curl_slist_append(headerList, "flag: libcurl");
      	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerList);
      
      	// 设置不校验证书,https请求时使用
      	curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
          curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
      
      	// 设置回调函数获取响应体数据
      	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, responseBodyCallback);
      	curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&response);
      
      	// 设置回调函数获取响应头数据
      	curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, responseHeaderCallback);
      	curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void*)&responseHeader);
      
      	// 超时时间
      	curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5);
      
      	// 执行请求
      	CURLcode res = curl_easy_perform(curl);
      
      	// 检查错误
      	if(res == CURLE_OK){
      		// 获取状态码
      		int responseCode = 0;
      		curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
      		std::cout << "code : "<<responseCode << std::endl;
      
      		std::cout << "responseHeader size : "<<responseHeader.headerSize << std::endl;
      		std::cout << "responseHeader header : "<<responseHeader.header.c_str() << std::endl;
      
      		std::cout << "response size : "<<response.bodySize << std::endl;
      		std::cout << "response body : "<<response.body.c_str() << std::endl;
      	}else{
      		std::cout<<curl_easy_strerror(res)<<std::endl;
      	}
      
      	curl_slist_free_all(headerList);
      
      	// 清理
      	curl_easy_cleanup(curl);
      
      
      	return 0;
      }
    
  • 完整工程已上传至gitee 测试工程

参考

  • 官方API文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1384549.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前后端的那些事】开源!前后端环境搭建+树形结构表格实现

文章目录 1. 前后端项目环境搭建2. table-tree2.1 后端准备2.2 前端准备 前言&#xff1a;最近写项目&#xff0c;发现了一些很有意思的功能&#xff0c;想写文章&#xff0c;录视频把这些内容记录下。但这些功能太零碎&#xff0c;如果为每个功能都单独搭建一个项目&#xff0…

spring cloud feign demo

1. 工程结构 2. 父工程pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.…

还在因为版本不一致重装node吗,用它试试

一、卸载nodejs 首先卸载已安装的nodejs&#xff0c;总体分三步 1)打开控制面板&#xff0c;卸载nodejs 2)打开计算机->高级->环境变量&#xff0c;删除path中nodejs相关的配置 3)打开nodejs安装目录&#xff0c;整体删除 打开cmd&#xff0c;输入以下命令&#xff…

浅谈 Raft 分布式一致性协议|图解 Raft

前言 大家好&#xff0c;这里是白泽。本文是一年多前参加字节训练营针对 Raft 自我整理的笔记。 本篇文章将模拟一个KV数据读写服务&#xff0c;从提供单一节点读写服务&#xff0c;到结合分布式一致性协议&#xff08;Raft&#xff09;后&#xff0c;逐步扩展为一个分布式的…

SpringBoot原理(@Conditional)—三种自动配置方法、步骤详解

简介&#xff1a;我们一直在说基于SpringBoot开发简单、快捷&#xff0c;但是总是不太清楚为什么会有这样的便利&#xff0c;对于开发人员来说我们不仅要知其然&#xff0c;还要知其所以然&#xff0c;这篇文章就是说明SpringBoot的底层原理&#xff0c;让读者对SpringBoot底层…

瑞_Java开发手册_(二)异常日志

文章目录 异常日志的意义(一) 错误码(二) 异常处理(三) 日志规约附&#xff1a;错误码列表 &#x1f64a;前言&#xff1a;本文章为瑞_系列专栏之《Java开发手册》的异常日志篇&#xff0c;本篇章主要介绍异常日志的错误码、异常处理、日志规约。由于博主是从阿里的《Java开发手…

逆水行舟 不进则退

目录 一、前言 二、2023年度总结 三、2024展望未来 一、前言 这是我从工作以来到现在最喜欢的一句话&#xff0c;我想把这句话送给自己也想送给大家。 2019年7月实习到现在已经过去了四年多&#xff0c;进入2024年也迎来了我工作生涯的第五个年头。 在这个行业里&#xff…

宠物空气净化器哪个牌子好?实惠的猫用空气净化器牌子推荐

对于养猫的朋友来说&#xff0c;猫咪掉毛绝对是一个让人头痛的问题。猫毛和皮屑会飘散在空气中&#xff0c;不仅会遍布全屋的各个角落&#xff0c;而且打扫起来也麻烦&#xff0c;特别是一些清理不了的猫毛&#xff0c;甚至还可能引起人的过敏反应&#xff0c;例如咳嗽和哮喘。…

PXIe-6396国产替代,8路AI(18位,14 MS/s/ch),2路A​O,24路DIO,PXI多功能I/O模块

PXIe&#xff0c;8路AI&#xff08;18位&#xff0c;14 MS/s/ch&#xff09;&#xff0c;2路A​O&#xff0c;24路DIO&#xff0c;PXI多功能I/O模块 PXIe-6396是一款同步采样的多功能DAQ设备。该模块提供了模拟 I/O、数字I/O、四个32位计数器和模拟和数字触发。板载NI-STC3定时…

RT-Thread GD32F4xx实现SD卡热插拔检测功能

GD32F470移植RT-Thread操作系统添加SD卡功能&#xff0c;增加SD卡热插拔检测 一、RT-Thread移植sd卡功能二、实现SD卡热插拔检测原理三、软件实现过程四、延展之ASSERT ERROR&#xff0c;即RT-Thread断言错误五、延展之STM32 SD卡热插拔检测六、结束语 一、RT-Thread移植sd卡功…

Java研学-过滤与监听

一 过滤器 Filter 1 介绍 Java Web 组件之一(Servlet 的功能)&#xff0c;可改变一个request和修改一个response。Filter不是Servlet&#xff0c;不能产生一个response&#xff0c;它是在一个request 到达Servlet之前预处理 request&#xff0c;也可以在response离开Servlet 后…

新一代数字原住民:市场痛点与“繁”思维应对之道

随着科技的迅速发展&#xff0c;尤其是互联网的普及&#xff0c;新一代数字原住民经营者已经逐渐成为市场的主力军。不同于传统的消费者&#xff0c;有着独特的消费习惯和心理需求。企业要在这激烈的市场竞争中获得优势&#xff0c;深入了解这一群体的特征和心理、行为&#xf…

【EMC专题】浪涌的成因与ICE 61000-4-5标准

什么是浪涌? 浪涌是一种无法预料的瞬态电压或电流尖峰,由附近的电子产品或是环境导致。 了解浪涌非常重要,因为浪涌有可能会导致设备的电气过应力损坏,造成系统故障等。 对于系统设计来说,重要的一点是我们如果无法控制浪涌的产生,那么只能通过将瞬态峰值电流导入到地,…

Pyside6/PyQt6中的QTimer类:轻松实现定时任务

文章目录 📖 介绍 📖🏡 环境 🏡📒 使用方法 📒📝 参数说明📝 常用方法⚓️ 相关链接 ⚓️📖 介绍 📖 在PySide/PyQt框架中,QTimer是一个核心类,主要用于在指定的间隔时间后触发某些事件。QTimer为开发者提供了一种处理和调度重复或单次动作的简便方式。 …

CSP网络结构实战 - 降低计算量的特征融合方式

CSP网络结构实战 - 降低计算量的特征融合方式 CSP网络结构实战 - 降低计算量的特征融合方式0. 引言1. CSP网络结构简介1.1 核心思想1.2 解决的问题 2. 实验验证2.1 CSP网络模型构建2.2 数据读取与预处理2.3 模型训练与验证 3. 对比实验4. 结果与总结 CSP网络结构实战 - 降低计算…

change事件传递多个参数

1.传递value页面参数 change"handleChange($event,123)" 2.传递选中的keyvalue或是选中的item 我用的是a-auto-complete&#xff0c;试验了用a-select也可以 就是在option里面&#xff0c;:value"JSON.stringify(d)" 然后在eval(( value ))转化就可…

Python中如何简化if...else...语句

一、引言 我们通常在Python中采用if...else..语句对结果进行判断&#xff0c;根据条件来返回不同的结果&#xff0c;如下面的例子。这段代码是一个简单的Python代码片段&#xff0c;让用户输入姓名并将其赋值给变量user_input。我们能不能把这几行代码进行简化&#xff0c;优化…

CTFhub-HTTP响应包源代码查看

CTFhub-Web-Web前置技能-“HTTP响应包源代码查看” 题目分析 页面空白&#xff0c;想到flag也许在源代码中 解题过程 F12&#xff0c;在element中&#xff0c;看到html代码&#xff0c;在其body中找到flag

对闭包的理解

概念&#xff1a; 一个函数对周围状态的引用捆绑在一起&#xff0c;闭包让开发者可以从内部函数访问外部 函数的作用域 简单理解&#xff1a;闭包 内层函数 外层函数的变量 一个函数对周围状态的引用捆绑在一起&#xff0c;闭包让开发者可以从内部函数访问外部 函数的作…

10.9.2 std::function 存储函数对象 Page184

41行&#xff0c;pending只是inc的复制品&#xff0c;所以43&#xff0c;44行&#xff0c;不会改变inc()的值 demo_function2()的运行结果&#xff1a; 59行&#xff0c;pending是inc的引用&#xff0c;所以61,62行将会改变inc()的值