libcurl API介绍及简单编程

2023-05-16


       libcurl编程,主要采用callback function(回调函数) 的形式完成传输任务,用户在启动传输前设置好各类参数
和回调函数,当满足条件时 libcurl 将调用用户的回调函数实现特定功能。

下面是利用libcurl 完成传输任务流程:

1. curl_global_init();    //初始化libcurl 创造全局句柄

2. curl_easy_init();      //函数得到easy interface型指针  创造局部变量句柄

3. curl_easy_setopt();    //设置传输选项  给句柄设置一些参数

4. curl_easy_setopt();    //设置传输选项 实现回调函数以完成用户特定任务

5. curl_easy_perform();   //完成传输任务 提交句柄 阻塞等待

6. curl_easy_cleanup();   //释放内存

 

 get请求例子: 


//get请求
#include <stdio.h>
#include <stdlib.h>
#include <curl.h>

/*
* ptr      表示收到服务器返回数据的首地址
* size     表示返回每个数据的大小
* nmemb    表示返回数据的个数
* userdata 用户给该回调函数传递的形参   curl_easy_setopt(curl, CURLOPT_WRITEDATA, "abc"); 设置的字符串"abc"
*          这个可以用来标识传输命令 返回的数据 来自命令 "abc",根据这个命令来处理这个数据
*/
size_t write_callback(char *ptr, size_t size, size_t nmemb, void* userdata) {
	long sizes = size * nmemb;

	char* recv = new char[sizes];
	memcpy(recv, (char*)ptr, sizes);//复制传过来的数据

	printf("传过来的数据: %s", recv);

	return sizes;
}

int main(void) {

	//1. 创建一个curl句柄
	CURL* curl = nullptr;
	CURLcode res;

	//2. 初始化一个curl句柄
	curl = curl_easy_init();

	//3. 给该句柄设定一些参数 (封装一个http请求消息) 
	curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8888"); //http://www.baidu.com
	//curl_easy_setopt(curl, CURLOPT_URL, "http:/101.200.190.150:8090/login?username=123&passwd=445");

	//给当前句柄设置一个 处理从服务器返回数据的回调函数
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);

	//给回调函数传递一个形参
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, "abc");

	//4. 将curl句柄 向远程服务器 提交请求 并得到一个返回值
	res = curl_easy_perform(curl);  //阻塞等待服务器返回
	if(res != CURLE_OK) {
		printf("curl easy perform error res = %d\n", res);
		return 1;
	}

	//5. 处理服务器返回数据

	//6. 清空 释放句柄内存空间
	curl_easy_cleanup(curl);

	return 0;
}

 

post请求例子:

#include <stdio.h>
#include <stdlib.h>
#include <curl.h>

#define POSTDATA   "{\"username\" : \"gailun\", \"password\" : \"123123\"}"

int main(void) {

	//1. 创建一个curl句柄
	CURL* curl = nullptr;
	CURLcode res;

	//2. 初始化一个curl句柄
	curl = curl_easy_init();

	if(nullptr == curl) {
		printf("curl init error");
		return 0;
	}

	//3. 给该句柄设定一些参数 (封装一个http请求消息) 
	curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8888"); //http://www.baidu.com

	//给当前curl变成post请求
	curl_easy_setopt(curl, CURLOPT_POST, 1);

	//给当前curl设置需要传递post数据
	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, POSTDATA);

	//4. 将curl句柄 向远程服务器 提交请求 并得到一个返回值
	res = curl_easy_perform(curl);  //阻塞等待服务器返回
	if(res != CURLE_OK) {
		printf("curl easy perform error res = %d\n", res);
		return 1;
	}

	//5. 处理服务器返回数据

	//6. 清空 释放句柄内存空间
	curl_easy_cleanup(curl);

	return 0;
}

 

 

 

 

下面转载其他博客对函数进行详细说明:

 

1>: curl_global_init();//全局初始化 函数

应用程序在使用libcurl之前,必须先初始化libcurl。libcurl只需初始化一次。可以使用以下语句进行初始化:

curl_global_init();

curl_global_init()接收一个参数(三种),告诉libcurl如何初始化。

参数CURL_GLOBAL_ALL 会使libcurl初始化所有的子模块和一些默认的选项,通常这是一个比较好的默认参数值。还有两个可选值:

参数CURL_GLOBAL_WIN32只能应用于Windows平台。它告诉libcurl初始化winsock库。如果winsock库没有正确地初始化,应用程序就不能使用socket。在应用程序中,只要初始化一次即可。

参数CURL_GLOBAL_SSL如果libcurl在编译时被设定支持SSL,那么该参数用于初始化相应的SSL库。同样,在应用程序中,只要初始化一次即可。

      libcurl有默认的保护机制,如果在调用curl_easy_perform时它检测到还没有通过curl_global_init进行初始化,libcurl会根据当前的运行时环境,自动调用全局初始化函数。但必须清楚的是,让系统自已初始化不是一个好的选择。

   当应用程序不再使用libcurl的时候,应该调用curl_global_cleanup来释放相关的资源。

   在程序中,应当避免多次调用curl_global_init和curl_global_cleanup。它们只能被调用一次。

 

2>:curl_version_info() //返回的结构体来获取运行时的具体信息

   curl_version()

//通常用法:

cout<< curl_version()<<endl;//当前版本的字符串描述

//当前版本的详细信息

curl_version_info_data *pversion = curl_version_info(CURLVERSION_NOW);

//---------------------------easy interface

 

 首先介绍libcurl中被称为easy interface的api函数,所有这些函数都是有相同的前缀:curl_easy 。

3>:curl_easy_init();

        要使用easy interface,首先必须创建一个easy handle,easy handle用于执行每次操作。基本上,每个线程都应该有自己的easy handle用于数据通信(如果需要的话)。千万不要在多线程之间共享同一个easy handle。下面的函数用于获取一个easy handle :

   CURL *easy_handle = curl_easy_init();

    在easy handle上可以设置属性和操作(action)。easy handle就像一个逻辑连接,用于接下来要进行的数据传输。

4>:curl_easy_setopt();

        使用curl_easy_setopt函数可以设置easy handle的属性和操作,这些属性和操作控制libcurl如何与远程主机进行数据通信。一旦在easy handle中设置了相应的属性和操作,它们将一直作用该easy handle。也就是说,重复使用easy hanle向远程主机发出请求,先前设置的属性仍然生效。

 easy handle的许多属性使用字符串(以/0结尾的字节数组)来设置。通过curl_easy_setopt函数设置字符串属性时,libcurl内部会自动拷贝这些字符串,所以在设置完相关属性之后,字符串可以直接被释放掉(如果需要的话)。

        easy handle最基本、最常用的属性是URL。你应当通过CURLOPT_URL属性提供适当的URL:

       curl_easy_setopt(easy_handle, CURLOPT_URL, "http://blog.csdn.net/JGood ");

        假设你要获取URL所表示的远程主机上的资源。你需要写一段程序用来完成数据传输,你可能希望直接保存接收到的数据而不是简单的在输出窗口中打印它们。所以,你必须首先写一个回调函数用来保存接收到的数据。回调函数的原型如下:

       size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);

        可以使用下面的语句来注册回调函数,回调函数将会在接收到数据的时候被调用:

        curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, write_data);

        可以给回调函数提供一个自定义参数,libcurl不处理该参数,只是简单的传递:

        curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &internal_struct);

        如果你没有通过CURLOPT_WRITEFUNCTION属性给easy handle设置回调函数,libcurl会提供一个默认的回调函数,它只是简单的将接收到的数据打印到标准输出。你也可以通过CURLOPT_WRITEDATA属性给默认回调函数传递一个已经打开的文件指针,用于将数据输出到文件里。

        curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, *fp);

上传数据到远程站点

    libcurl提供协议无关的方式进行数据传输。所以上传一个文件到FTP服务器,跟向HTTP服务器提交一个PUT请求的操作方式是类似的:

1. 创建easy handle或者重用先前创建的easy handle。

2. 设置CURLOPT_URL属性。

3. 编写回调函数。在执行上传的时候,libcurl通过回调函数读取要上传的数据。(如果要从远程服务器下载数据,可以通过回调来保存接收到的数据。)回调函数的原型如下:

size_t function(char *bufptr, size_t size, size_t nitems, void *userp);

    bufptr指针表示缓冲区,用于保存要上传的数据,size * nitems是缓冲区数据的长度,userp是一个用户自定义指针,libcurl不对该指针作任何操作,它只是简单的传递该指针。可以使用该指针在应用程序与libcurl之间传递信息。

4. 注册回调函数,设置自定义指针。语法如下:

// 注册回调函数

curl_easy_setopt(easy_handle, CURLOPT_READFUNCTION, read_function);

// 设置自定义指针

curl_easy_setopt(easy_handle, CURLOPT_READDATA, &filedata);

5. 告诉libcurl,执行的是上传操作。

curl_easy_setopt(easy_handle, CURLOPT_UPLOAD, 1L);

    有些协议在没有预先知道上传文件大小的情况下,可能无法正确判断上传是否结束,所以最好预先使用CURLOPT_INFILESIZE_LARGE属性:告诉它要上传文件的大小:

/* in this example, file_size must be an curl_off_t variable */

curl_easy_setopt(easy_handle, CURLOPT_INFILESIZE_LARGE, file_size);

6. 调用curl_easy_perform。

    接下来,libcurl将会完成剩下的所有工作。在上传文件过程中,libcurl会不断调用先前设置的回调函数,用于将要上传的数据读入到缓冲区,并执行上传。

 

5>: curl_easy_perform(easy_handle);//将执行真正的数据通信:

        curl_easy_perfrom将连接到远程主机,执行必要的命令,并接收数据。当接收到数据时,先前设置的回调函数将被调用。libcurl可能一次只接收到1字节的数据,也可能接收到好几K的数据,libcurl会尽可能多、及时的将数据传递给回调函数。回调函数返回接收的数据长度。如果回调函数返回的数据长度与传递给它的长度不一致(即返回长度 != size * nmemb),libcurl将会终止操作,并返回一个错误代码。

 当数据传递结束的时候,curl_easy_perform将返回一个代码表示操作成功或失败。

 easy handle在完成一次数据通信之后可以被重用。这里非常建议你重用一个已经存在的easy handle。如果在完成数据传输之后,你创建另一个easy handle来执行其他的数据通信,libcurl在内部会尝试着重用上一次创建的连接。

 

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

libcurl API介绍及简单编程 的相关文章

随机推荐

  • 使用cmake构建C++ imgui上手项目(支持Windows,Mac,Linux)

    优秀的即时渲染C 43 43 GUI开发框架imgui xff08 https github com ocornut imgui xff09 在很多场合能发挥非常棒的作用 但是由于官方源码仓库一直没有提供基于cmake构建和创建新项目的工具
  • 使用cmake构建C++ workflow上手项目(支持Windows,Linux)

    开源的C 43 43 后端开发框架workflow xff08 https github com sogou workflow xff09 已经在成熟的互联网公司得到非常稳定广泛的应用 xff0c 它结合了网络 异步 计算多个后端常用场景
  • 使用cmake构建C++ live555流媒体服务上手项目(支持Windows,Linux)

    开源的流媒体视频和音频RTSP开发框架live555 xff08 http www live555 com xff09 对于学习和构建音视频流媒体或者直播服务是很方便的 官方的源码包对各平台编译单独列出了对应的makefile xff0c
  • C++20新特性

    目录 新增关键字 keywords conceptrequiresconstinitconstevalco awaitco returnco yieldchar8 t 新增标识符 Identifies importmodule 模块 Mod
  • pytorch导出模型并使用onnxruntime C++部署加载模型推理

    机器学习的框架众多 xff0c 为了方便复用和统一后端模型部署推理 xff0c 业界主流都在采用onnx格式的模型 xff0c 支持pytorch xff0c tensorflow xff0c mxnet多种AI框架 为了提高部署推理的性能
  • cocos2dx实例开发之飞机大战

    曾经 xff0c 微信里面可以玩一个打飞机的小游戏 xff0c 很有趣 xff0c 后来又没有了 xff0c 这里基于原版素材写了一个高仿微信打飞机的小游戏 预览 工程结构 环境 Mac os Mojavexcode 7 0cocos2dx
  • 调试leetcode代码:使用playground来调试

    leetcode在线编辑界面 在使用LeetCode时 xff0c 想要在本地上调试代码 xff0c 提供main函数的方法 xff1a 在线代码编辑功能 1 在红圈处选择你想要使用的语言 2 在黄圈处编写代码 3 在蓝圈处可选编辑测试案例
  • 蓝牙5/4.2/4.1/4.0数据吞吐率

    先给出结论 xff1a 蓝牙4 0 4 1的吞吐率 为0 305Mbps xff1b 蓝牙4 2的吞吐率 为0 803Mbps xff1b 蓝牙5的吞吐率 为1 434Mbps xff08 前提 xff1a 使用2Mbps调制速率 xff1
  • BLE 协议栈组成介绍

    框图 xff1a 1 协议由Host层和Controller层组成 xff1b 2 Controller层 xff1a PHY xff1a 基带物理层 xff0c 相关概念 xff1a 频段 调制 射频信道 发射功率 xff1b LL xf
  • ATT 的功能

    GATT Profile xff0c 通用属性配置 xff1a 类比位做煤球的模子 xff0c 每个SIG组织成员都可以向SIG提交这个 模子 xff0c 如果审核通过了 xff0c 那么这个模子就成为全世界通用的了 xff0c 不用管这个
  • FR8016HA & MS1791 & PHY6222 & TLSR8251 & YC1171 & HS6621 & BK3432 & N32WB031 对比介绍

    富苪坤 FR8016HA 巨微 MS1791 奉加微 PHY6222 泰凌微 TLSR8251 易兆微 YC1171 昂瑞微 HS6621 博通 BK3432 国民技术 N32WB031 芯片简介 FR8016HA 是一款面向 SOC xf
  • AD7606分析讲解

    一 ad7606数据手册分析 引脚配置和功能描述 ADC7606的典型工作特性 FFT xff08 快速傅里叶变换 xff09 http azaleasays com 2008 10 17 fft and digital signal pr
  • 什么是航位推算(Dead Reckoning )

    只有同时接收三到四个GPS GNSS卫星的信号才能实现精确的GPS GNSS定位 当仅依靠GPS GNSS定位时 xff0c 可能会出现位置精度降低或丢失的情况 例如 xff0c 当车辆在无法接收GPS GNSS信号的区域 xff08 隧道
  • STM32F103系列引脚定义-功能图

    器件功能和配置 xff08 STM32F103XX增强型 xff09 系统结构 管脚图
  • 如何用keil5打开keil4的工程

    参考网友的方法 xff1a 1 到http www2 keil com mdk5 legacy 官网下载keil4的支持包 2 正常流程安装所下载的安装包 xff1b 3 安装完成后 xff0c 用keil5打开工程 xff08 keil4
  • NMEA-0183 协议简介

    NMEA 0183 是美国国家海洋电子协会 xff08 National Marine Electronics Association xff09 为海用电子设备制定的标准格式 目前业已成了 GPS 北斗导航设备统一的 RTCM xff08
  • 串口通信校验方式(even,odd,space,mark)UART数据波形分析

    1 even 每个字节传送整个过程中bit为1的个数是偶数个 xff08 校验位调整个数 xff09 2 odd 每个字节穿送整个过程中bit为1的个数是奇数个 xff08 校验位调整个数 xff09 3 noparity没有校验位 4 s
  • Linex Ubuntu环境下 Intel Realsense D435I 驱动+ROS驱动安装配置

    任务背景 在ROS环境中使用d435i xff0c 订阅图像和imu数据 任务概述 实现在ros中使用d435i主要有两步骤 xff1a 1 安装d435i sdk xff0c 即librealsense xff1b 2 安装realsen
  • C++ 实现简单Http服务器

    实现一个简单的Http服务器 xff0c 基于windows 平台 总共五个文件 HttpServer hpp HttpServer cpp Utils hpp Utils cpp main cpp Utils hpp span class
  • libcurl API介绍及简单编程

    libcurl编程 xff0c 主要采用callback function 回调函数 的形式完成传输任务 xff0c 用户在启动传输前设置好各类参数 和回调函数 xff0c 当满足条件时 libcurl 将调用用户的回调函数实现特定功能 下