libcurl 简单使用

LibCurl是一个开源的免费的多协议数据传输开源库,该框架具备跨平台性,开源免费,并提供了包括HTTPFTPSMTPPOP3等协议的功能,使用libcurl可以方便地进行网络数据传输操作,如发送HTTP请求、下载文件、发送电子邮件等。它被广泛应用于各种网络应用开发中,特别是涉及到数据传输的场景。

官网:curl

下载安装:curl - Download

安装步骤

说明:在编译任何开源代码前可以先看看README, INSTALL等文件, 会提供如何编译的信息。在此教程中通过阅读README和GIT-INFO文 件可以得到很多编译安装信息。 在GIT-INFO 中很明显地说了执行: ./buildconf产生configure配置文件。

  1. ./buildconf(产生configure配置文件)
  2. ./configure --with-openssl (我是默认安装openssl的
  3. make
  4. make install(默认库文件安装在/usr/local/lib 头文件安装在/usr/local/include  --->安装要root权限)

libcurl库的API接口

(1)初始化curl句柄

CURL* curl = NULL;
curl = curl_easy_init();

(2)设置curl的url

curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:9001/login");

(3)开启post请求开关

curl_easy_setopt(curl, CURLOPT_POST, true);

(4)添加post数据

 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_str);

(5)设定一个处理服务器响应的回调函数

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, deal_response);

(6)给回调函数传递一个形参

curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);

(7)向服务器发送请求,等待服务器的响应

res = curl_easy_perform(curl);

测试用例(实现网页下载保存): 

// 采用CURLOPT_WRITEFUNCTION 实现网页下载保存功能
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>#include <curl/curl.h>
#include <curl/easy.h>FILE *fp;  //定义FILE类型指针//这个函数是为了符合CURLOPT_WRITEFUNCTION而构造的,完成数据保存功能
size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)  
{int written = fwrite(ptr, size, nmemb, (FILE *)fp);return written;
}int main(int argc, char *argv[])
{CURL *curl;if (argc != 3){fprintf(stderr, "usage: %s url filename\n", argv[0]);exit(-1);}curl_global_init(CURL_GLOBAL_ALL);  curl = curl_easy_init();curl_easy_setopt(curl, CURLOPT_URL, argv[1]);  if((fp = fopen(argv[2],"w")) == NULL){curl_easy_cleanup(curl);exit(1);}//CURLOPT_WRITEFUNCTION 将后继的动作交给write_data函数处理curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);  curl_easy_perform(curl);curl_easy_cleanup(curl);exit(0);
}

编译运行: 


该库的使用很简单,首先我们需要调用curl_easy_init()函数对CURL对象进行初始化,接着通过调用curl_easy_setopt()并传入一个访问URL链接,当访问成功后则可curl_easy_perform()函数得到访问结果。

<1>调curl_global_init()接口进行全局初始化

        一个进程只需调用一次。如果一次都未调用,curl_easy_init()接口内部会自动调curl_global_init(),因为curl_easy_init()并不是多线程安全,如果两个线程同时调用curl_easy_init(),会概率出现一个线程在没有全局初始化下就进行网络传输导致崩溃,于是强烈建议显示调用curl_global_init()进行libcurl库进行全局初始化。

<2>调curl_easy_init()接口分配一个网络传输对象

因为libcurl是以C语言接口形式提供,所以后续调用的接口都需要提供该接口返回的句柄。

<3>调curl_easy_init()接口分配一个网络传输对象

   因为libcurl是以C语言接口形式提供,所以后续调用的接口都需要提供该接口返回的句柄。

curl_easy_setopt()函数第二个参数可以使用多种类型的变量定义,我们可以通过传入不同的常量来定义请求头中的参数,

CURLOPT_VERBOSE设置值为1启用调试输出,此时要设置CURLOPT_DEBUGFUNCTION 调试输出函数,排查问题时使用。
CURLOPT_URL设置URL地址
CURLOPT_PUT设置HTTP请求方法为PUT,CURLOPT_POST设置HTTP请求方法为POST,要设置HTTP请求方法为DELETE或PATCH,就得用CURLOPT_CUSTOMREQUEST
CURLOPT_POSTFIELDS设置HTTP请求body内容,CURLOPT_POSTFIELDSIZE设置body大小,如果body内容是以\0结尾,可以不指定body大小。
 
CURLOPT_HTTPHEADER设置HTTP头部,HTTP头部是用curl_slist结构的链表,curl_slist_append()添加HTTP头部,可以调多次添加多个头部,curl_slist_free_all()释放curl_slis对象。
 
CURLOPT_WRITEFUNCTION设置HTTP请求body的数据输出函数,同时可以指定CURLOPT_WRITEDATA作为输出函数的user_data,libcurl会透传user_data。
CURLOPT_TIMEOUT_MS设置网络请求总超时值,CURLOPT_CONNECTTIMEOUT_MS设置网络socket连接超时值。
 
CURLOPT_SSL_VERIFYPEER设置0时不校验服务端,HTTPS请求时如果本地没有服务端证书,需要设置为0。

官方api文档

libcurl - curl_easy_setopt()

<4>调curl_easy_getinfo()接口获取网络请求响应信息

        它类似于curl_easy_setopt()接口,第2个参数指定获取项,第3个参数依第2个参数不同而不同,比较常用的是CURLINFO_RESPONSE_CODE,获取状态码。

<5>调curl_easy_cleanup()接口释放资源

<6>调curl_global_cleanup()接口释放全局资源

下面的demo代码介绍如何使用libcurl库进行HTTP GET和POST请求

#include <stdio.h>
#include <curl/curl.h>
#include <string>size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{((std::string*)userdata)->append(ptr, nmemb);return nmemb;
}int main(void)
{curl_global_init(CURL_GLOBAL_DEFAULT);CURL* curl = curl_easy_init();if (curl) {        curl_easy_setopt(curl, CURLOPT_URL, "https://www.baidu.com");// no certificate, not verify server certificatecurl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);std::string response_data;curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);CURLcode res = curl_easy_perform(curl);if (res != CURLE_OK){fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res));}else{long response_code;curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);printf("response code %ld \n", response_code);printf("response data : \n ");printf(response_data.c_str());}curl_easy_cleanup(curl);}curl_global_cleanup();return 0;
}

运行结果: 

#include <stdio.h>
#include <curl/curl.h>
#include <string>size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{((std::string*)userdata)->append(ptr, nmemb);return nmemb;
}int main()
{curl_global_init(CURL_GLOBAL_DEFAULT);CURL* curl = curl_easy_init();if (curl){// set urlcurl_easy_setopt(curl, CURLOPT_URL, "https://jsonplaceholder.typicode.com/posts");// no certificate, not verify server certificatecurl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);// set http methodcurl_easy_setopt(curl, CURLOPT_POST, 1);// set headerstruct curl_slist * slist = nullptr;slist = curl_slist_append(slist, "Content-Type : application/json");curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);// set bodystd::string body = "{\\"title\":\"libcurl post title\",\\"body\" : \"libcurl post body\",\\"userId\" : 1}";curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());// set response callback to read responsestd::string response_data;        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);CURLcode res = curl_easy_perform(curl);if (res != CURLE_OK){fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res));}else{// get response codelong response_code;curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);printf("response code %ld \n", response_code);printf("response data : \n ");printf("%s", response_data.c_str());}curl_slist_free_all(slist);curl_easy_cleanup(curl);}curl_global_cleanup();return 0;
}

运行结果: 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器数据恢复—V7000存储raid5数据恢复案例

服务器数据恢复环境&#xff1a; P740AIXSybaseV7000存储阵列柜&#xff0c;阵列柜上有12块SAS机械硬盘&#xff08;包括1块热备盘&#xff09;。 服务器故障&#xff1a; 管理员在日常巡检过程中发现阵列柜中有一块磁盘发生故障&#xff0c;于是更换磁盘并同步数据&#xff0…

HTTP协议安全传输教程

HTTP协议有多个版本&#xff0c;包括但不限于HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2和HTTP/3。这些版本各自具有不同的特点和改进&#xff0c;以适应网络技术的发展和满足不同的需求。例如&#xff0c;HTTP/1.0使用文本格式传输数据&#xff0c;简单易用且兼容性好&#xff0c;…

电路笔记 : esp32pico-d4最小系统原理图

ESP32-PICO-D4 ESP32-PICO-D4是一款基于ESP32的系统级封装(SiP)模组&#xff0c;可提供完整的Wi-Fi和蓝牙功能。该模组的外观尺寸仅(7.0000.100)mm(7.0000.100)mm(0.9400.100)mm&#xff0c;整体占用的PCB面积最小&#xff0c;已集成1个4MB串行外围设备接口(SPI) flash。 ESP3…

网络层协议——IP协议

目录 IP协议 IP协议格式 分片与组装 网段划分 特殊IP地址 IP地址的数量限制 私有IP地址和公网IP地址 路由 路由表生成算法 IP协议 IP协议全称为“网际互连协议&#xff08;Internet Protocol&#xff09;”&#xff0c;IP协议是TCP/IP体系中的网络层协议。 在应用层我…

外卖小程序实战-接单后小票机自动打印订单

1、导入小票机的sdk https://www.feieyun.com/api/API-JAVA.zip public static String addprinter(String snlist){//通过POST请求&#xff0c;发送打印信息到服务器RequestConfig requestConfig RequestConfig.custom() .setSocketTimeout(30000)//读取超时 .setConnectTi…

DePIN打猎之旅:AI算力作饵,道阻且长

出品&#xff5c;OKG Research 作者&#xff5c;Hedy Bi 香港Web3嘉年华已告一段落&#xff0c;然而Web3自由的脉搏还在跳动&#xff0c;并不断向其他行业渗透。和上一轮周期相比&#xff0c;本轮牛市开启的逻辑是由“原生创新叙事”转变成“主流认可&#xff0c;资金驱动”的…

C语言详解指针

目录 一、指针的概念 1.1内存与地址 例子&#xff1a; 二、变量的指针与指针变量 2.1、指针变量的定义及使用 1、指针变量的定义 2、指针变量的使用 2.2 指针变量的大小 2.3、指针-整数 2.4、void*指针 三、指针的运算 1、指针- 整数 2、指针-指针 3、指针的关系运…

一套3种风格经典的wordpress免费主题模板

wordpress免费企业主题 https://www.wpniu.com/themes/39.html 免费wordpress企业模板 https://www.wpniu.com/themes/43.html 免费wordpress企业主题 https://www.wpniu.com/themes/44.html

使用docker部署数据可视化平台Metabase

目前公司没有人力开发数据可视化看板&#xff0c;因此考虑自己搭建开源可视化平台MetaBase。在此记录下部署过程~ 一、镜像下载 docker pull metabase/metabase:latest 运行结果如下&#xff1a; 二、创建容器 docker run -dit --name matebase -p 3000:3000\ -v /home/loc…

Python编程之旅:深入探索强大的容器——列表

在Python编程的世界中&#xff0c;容器&#xff08;Containers&#xff09;是一种用于存储多个项目的数据结构。其中&#xff0c;列表&#xff08;List&#xff09;是最常用且功能强大的容器之一。无论是初学者还是资深开发者&#xff0c;掌握列表的使用方法和技巧都是提升Pyth…

四.吊打面试官系列-数据库优化-Mysql锁和事务原理

前言 本篇文章主要讲解两块内容&#xff1a;Mysql中的锁和ACID原理&#xff0c;这2个部分是面试的时候被问的蛮多的看完本篇文章之后相信你对Mysql事务会有更深层次的理解&#xff0c;如果文章对你有所帮助请记得好评 一.Mysql中的锁 1.锁的分类 在Mysql中锁也分为很多种&a…

揭秘AI精准输出:如何构建完美的AIGC提示词?

揭秘AI精准输出&#xff1a;如何构建完美的AIGC提示词&#xff1f;&#x1f916; 文章目录 揭秘AI精准输出&#xff1a;如何构建完美的AIGC提示词&#xff1f;&#x1f916;摘要引言正文&#x1f4d8; 提示词的基本概念1. 什么是提示词&#xff1f;2. 提示词的作用 &#x1f4d…

Redis安装和使用(Ubuntu系统)

本节内容包括Redis简介、安装Redis和Redis实例演示等&#xff0c;Redis在Window系统安装教程可参考Redis安装与运行_厦大数据库实验室博客 Redis是一个键值&#xff08;key-value&#xff09;存储系统&#xff0c;即键值对非关系型数据库。Redis提供了Python、Ruby、Erlang、P…

【面试八股总结】排序算法(二)

参考资料 &#xff1a;阿秀 一、堆排序 堆排序基本思想是先把数组构造成一个大顶堆(父亲节点大于其子节点)&#xff0c;然后把堆顶(数组最大值&#xff0c;数组第一个元素)和数组最后一个元素交换&#xff0c;这样就把最大值放到了数组最后边。把数组长度n-1,再进行构造堆把剩…

开源AI聊天机器人应用程序模板; WrenAI用AI从数据中获取洞见;模拟多个代理人(agents)之间语言互动的仿真系统;语音数据集标注

✨ 1: gemini-chatbot 使用Next.js构建的开源AI聊天机器人应用程序模板 Gemini-chatbot是一个使用Next.js构建的开源AI聊天机器人应用程序模板。它利用了Vercel AI SDK、Google Gemini以及Vercel KV来提供一个功能丰富、可定制的聊天体验。这个聊天机器人可以支持多种不同的A…

GitHub repository - commits - branches - releases - contributors

GitHub repository - commits - branches - releases - contributors 1. commits2. branches3. releases4. contributorsReferences 1. commits 在这里可以查看当前分支的提交历史。左侧的数字表示提交数。 2. branches 可以查看仓库的分支列表。左侧的数字表示当前拥有的分…

我们试用了6款最佳Appium替代工具,有些甚至比Appium更好

Appium是一款知名的自动化测试工具&#xff0c;用于在iOS、Android和Windows等移动平台上运行测试。就开源移动测试自动化工具而言&#xff0c;虽然替代品有限&#xff0c;但它们确实存在。我们找到了一些优秀的Appium替代品&#xff0c;它们也可以满足自动化测试要求&#xff…

Jenkins上面使用pnpm打包

问题 前端也想用Jenkins的CI/CD工作流。 步骤 Jenkins安装NodeJS插件 安装完成&#xff0c;记得重启Jenkins。 全局配置nodejs Jenksinfile pipeline {agent anytools {nodejs "18.15.0"}stages {stage(Check tool version) {steps {sh node -vnpm -vnpm config…

RabbitMQ消息模型之Simple消息模型

simple消息模型 生产者 package com.example.demo02.mq.simple;import com.example.demo02.mq.util.ConnectionUtils; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection;import java.io.IOException;/*** author Allen* 4/10/2024 8:07 PM* versi…

HDFS的Shell操作

目录 一、进程启停管理 &#xff08;一&#xff09;一键启停脚本 &#xff08;二&#xff09;单进程启停 二、文件系统操作命令 &#xff08;一&#xff09;HDFS文件系统基本信息 1.前置介绍 &#xff08;二&#xff09;命令介绍 1.新旧版本命令介绍 2.创建文件夹 3.…