构建cURL (Client URL)跨平台通用接口
·
cURL 功能概述
cURL (Client URL) 是一个强大的命令行工具和库,用于在各种协议之间传输数据。
核心功能:
-
多协议支持:HTTP, HTTPS, FTP, FTPS, SCP, SFTP, TFTP 等
-
数据传输:GET, POST, PUT, DELETE 等HTTP方法
-
认证支持:Basic, Digest, OAuth, SSL证书等
-
代理支持:HTTP/HTTPS/SOCKS代理
-
文件操作:上传、下载、断点续传
上述设计的用法分析
1. HTTP POST 数据上传
// 用法:向API接口发送JSON数据
char* json_data = "{\"sensor\":\"temperature\",\"value\":25.5}";
char* api_url = "https://api.example.com/data";
CURL_Send_Msg(json_data, api_url, NULL, NULL);
2. 物联网设备数据上报
// 用法:物联网设备定期上报状态
void report_device_status() {
char status_data[256];
snprintf(status_data, sizeof(status_data),
"device_id=%s&temperature=%.2f&humidity=%.2f",
"DEVICE_001", 23.5, 65.2);
CURL_Send_Msg(status_data, "http://iot-platform.com/api/upload",
response_callback, response_buffer);
}
3. 日志收集系统
// 用法:将应用日志发送到日志服务器
size_t log_callback(char *ptr, size_t size, size_t nmemb, void *userdata) {
// 处理服务器响应
return size * nmemb;
}
void send_log_entry(const char* log_message) {
char log_data[512];
snprintf(log_data, sizeof(log_data),
"level=INFO&message=%s×tamp=%ld",
log_message, time(NULL));
CURL_Send_Msg(log_data, "http://log-server.com/ingest",
log_callback, NULL);
}
4. 监控数据推送
// 用法:系统监控指标推送到监控平台
typedef struct {
char metric_name[64];
double value;
long timestamp;
} MetricData;
size_t monitor_callback(char *ptr, size_t size, size_t nmemb, void *userdata) {
printf("Monitor response: %s\n", ptr);
return size * nmemb;
}
void push_metric(const char* name, double value) {
char metric_data[256];
snprintf(metric_data, sizeof(metric_data),
"metric=%s&value=%.2f&time=%ld",
name, value, time(NULL));
CURL_Send_Msg(metric_data, "http://monitor.com/api/metrics",
monitor_callback, NULL);
}
5. 配置中心客户端
// 用法:从配置中心拉取配置
size_t config_callback(char *ptr, size_t size, size_t nmemb, void *userdata) {
char* config_buffer = (char*)userdata;
strncpy(config_buffer, ptr, size * nmemb);
return size * nmemb;
}
void fetch_config(const char* device_id) {
char request_data[128];
char response_buffer[1024] = {0};
snprintf(request_data, sizeof(request_data), "device_id=%s", device_id);
CURL_Send_Msg(request_data, "http://config-center.com/get_config",
config_callback, response_buffer);
// 解析 response_buffer 中的配置信息
printf("Received config: %s\n", response_buffer);
}
6. 文件上传功能
// 用法:上传文件到云存储
void upload_file(const char* filename, const char* file_content) {
char upload_data[2048];
snprintf(upload_data, sizeof(upload_data),
"filename=%s&content=%s&type=text/plain",
filename, file_content);
CURL_Send_Msg(upload_data, "https://storage.example.com/upload",
NULL, NULL);
}
设计架构的优势用法
1. 微服务通信
// 服务间RPC调用
void service_rpc_call(const char* service_url, const char* method,
const char* params) {
char rpc_data[512];
snprintf(rpc_data, sizeof(rpc_data),
"{\"method\":\"%s\",\"params\":%s,\"id\":1}",
method, params);
CURL_Send_Msg(rpc_data, service_url, rpc_response_handler, NULL);
}
2. 数据同步
// 定时数据同步任务
void sync_data_to_cloud() {
while(1) {
// 收集本地数据
char sync_data[1024];
collect_sensor_data(sync_data, sizeof(sync_data));
// 同步到云端
CURL_Send_Msg(sync_data, "https://cloud-sync.com/api/data",
sync_callback, NULL);
sleep(60); // 每分钟同步一次
}
}
3. 事件通知
// 系统事件通知
void notify_event(const char* event_type, const char* event_data) {
char notification[512];
snprintf(notification, sizeof(notification),
"event_type=%s&data=%s&source=embedded_device",
event_type, event_data);
CURL_Send_Msg(notification, "http://notification-service.com/event",
NULL, NULL);
}
性能优化用法
1. 连接池模式
// 复用CURL句柄(需要修改原设计)
static CURL* global_curl_handle = NULL;
CURL* get_curl_handle() {
if (!global_curl_handle) {
global_curl_handle = curl_easy_init();
// 一次性设置常用选项
curl_easy_setopt(global_curl_handle, CURLOPT_TCP_KEEPALIVE, 1L);
}
return global_curl_handle;
}
2. 批量操作
// 批量发送数据点
void batch_send_metrics(MetricData* metrics, int count) {
char batch_data[4096];
char* cursor = batch_data;
// 构建批量数据
for(int i = 0; i < count; i++) {
cursor += snprintf(cursor, sizeof(batch_data) - (cursor - batch_data),
"%s=%.2f&", metrics[i].metric_name, metrics[i].value);
}
CURL_Send_Msg(batch_data, "http://metrics.com/batch", NULL, NULL);
}
安全相关用法
1. HTTPS通信
// 安全数据传输(需要扩展原设计)
void secure_data_transfer(const char* sensitive_data) {
// 实际应用中需要添加SSL证书验证等安全配置
CURL_Send_Msg(sensitive_data, "https://secure-api.example.com/transfer",
secure_callback, NULL);
}
这种设计特别适合:
-
嵌入式系统的远程通信
-
IoT设备的数据上报
-
分布式系统的组件通信
-
监控系统的数据收集
-
微服务架构的服务调用
源码构建
common_lib\curl> tree /f 文件夹 PATH 列表 卷序列号为 86C6-7427 E:. │ Makefile │ ├─bin ├─inc │ │ curlupload.h │ │ │ ├─curl │ │ curl.h │ │ curlver.h │ │ easy.h │ │ mprintf.h │ │ multi.h │ │ stdcheaders.h │ │ system.h │ │ typecheck-gcc.h │ │ │ └─openssl │ aes.h │ asn1.h │ asn1err.h │ asn1t.h │ asn1_mac.h │ async.h │ asyncerr.h │ bio.h │ bioerr.h │ blowfish.h │ bn.h │ bnerr.h │ buffer.h │ buffererr.h │ camellia.h │ cast.h │ cmac.h │ cms.h │ cmserr.h │ comp.h │ comperr.h │ conf.h │ conferr.h │ conf_api.h │ crypto.h │ cryptoerr.h │ ct.h │ cterr.h │ des.h │ dh.h │ dherr.h │ dsa.h │ dsaerr.h │ dtls1.h │ ebcdic.h │ ec.h │ ecdh.h │ ecdsa.h │ ecerr.h │ engine.h │ engineerr.h │ err.h │ evp.h │ evperr.h │ e_os2.h │ hmac.h │ idea.h │ kdf.h │ kdferr.h │ lhash.h │ md2.h │ md4.h │ md5.h │ mdc2.h │ modes.h │ objects.h │ objectserr.h │ obj_mac.h │ ocsp.h │ ocsperr.h │ opensslconf.h │ opensslv.h │ ossl_typ.h │ pem.h │ pem2.h │ pemerr.h │ pkcs12.h │ pkcs12err.h │ pkcs7.h │ pkcs7err.h │ rand.h │ randerr.h │ rand_drbg.h │ rc2.h │ rc4.h │ rc5.h │ ripemd.h │ rsa.h │ rsaerr.h │ safestack.h │ seed.h │ sha.h │ srp.h │ srtp.h │ ssl.h │ ssl2.h │ ssl3.h │ sslerr.h │ stack.h │ store.h │ storeerr.h │ symhacks.h │ tls1.h │ ts.h │ tserr.h │ txt_db.h │ ui.h │ uierr.h │ whrlpool.h │ x509.h │ x509err.h │ x509v3.h │ x509v3err.h │ x509_vfy.h │ ├─lib │ ├─lib_hisi │ │ libcrypto.a │ │ libcurl.a │ │ libssl.a │ │ │ └─lib_realtek │ libcrypto.a │ libcurl.a │ libssl.a │ ├─src │ curlupload.c │ curlupload.o │ └─test
curlupload.c
/* ==================== 头文件包含区域 ==================== */
#include <stdio.h> // 标准输入输出函数,用于printf等
#include <string.h> // 字符串处理函数
#include <stdlib.h> // 标准库函数,内存分配等
#include <pthread.h> // 多线程支持
#include "curlupload.h" // 自定义curl上传头文件
#include "curl.h" // libcurl主头文件
#include "easy.h" // libcurl简易接口头文件
/* ==================== 全局变量区域 ==================== */
static int curlInit = 0; // CURL初始化标志位:0-未初始化,1-已初始化
// 使用静态变量确保线程安全(但非线程安全实现)
/* ==================== 函数实现区域 ==================== */
/*********************************************************
** 传入参数:无
** 返回参数:0-成功,-1-失败
** 函数功能:curl 全局初始化(单例模式)
** 函数信息:确保CURL库只被初始化一次
** 其他信息:依据upload_curl_init()
** 设计模式分析:单例模式 - 通过静态变量curlInit确保全局只初始化一次
** 性能分析:轻量级初始化,避免重复初始化开销
***********************************************************/
int Global_curl_init()
{
CURLcode return_code; // 存储CURL函数返回值
/* 检查是否已经初始化,避免重复初始化 */
if(!curlInit)
{
curlInit = 1; // 设置初始化标志
/* 初始化CURL库,CURL_GLOBAL_ALL表示初始化所有可能的模块 */
return_code = curl_global_init(CURL_GLOBAL_ALL);
/* 检查初始化是否成功 */
if (CURLE_OK != return_code)
{
printf("curl_global_init fail\n"); // 初始化失败打印错误信息
curlInit = 0; // 重置初始化标志
return -1; // 返回错误码
}
printf("curl_global_init success\n"); // 初始化成功信息
}
return 0; // 成功返回
}
/*********************************************************
** 传入参数:
** char* Infoforsend: 要发送的数据内容
** char* urlforsend: 目标URL地址
** size_t(*callbackfun)(): 响应数据回调函数指针
** void *writedata: 写入数据的缓冲区指针
** 返回参数:0-成功,其他-CURL错误码
** 函数功能:使用CURL发送HTTP POST请求到七牛云
** 函数信息:封装了CURL的HTTP POST功能
** 其他信息:支持自定义回调函数处理响应数据
** 设计模式分析:工厂方法模式 - 封装了CURL对象的创建和配置过程
** 性能分析:设置连接超时10秒,DNS缓存60秒,使用无信号选项避免线程安全问题
***********************************************************/
int CURL_Send_Msg(char* Infoforsend, char* urlforsend, size_t(*callbackfun)(), void *writedata)
{
int ret = 0; // 函数返回值
struct curl_slist *headers = NULL; // HTTP头部链表
CURLcode return_code; // CURL操作返回码
/* 步骤1: 初始化CURL全局环境 */
if(Global_curl_init() != 0)
{
return -1; // 初始化失败直接返回
}
/* 步骤2: 创建CURL简易句柄(工厂方法模式) */
CURL *easy_handle = curl_easy_init();
if (NULL == easy_handle)
{
return -2; // 句柄创建失败
}
/* 步骤3: 设置CURL选项 */
curl_easy_setopt(easy_handle, CURLOPT_URL, urlforsend); // 设置目标URL
/* 步骤4: 设置HTTP请求头部 */
headers = curl_slist_append(headers, "Content-Type:application/x-www-form-urlencoded"); // 表单数据类型
headers = curl_slist_append(headers, "charset=UTF-8"); // 字符集编码
curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, headers); // 应用头部到请求
/* 步骤5: 设置POST请求参数 */
curl_easy_setopt(easy_handle, CURLOPT_POSTFIELDS, Infoforsend); // 设置POST数据
curl_easy_setopt(easy_handle, CURLOPT_POST, 1); // 启用POST方法
/* 步骤6: 设置性能和超时选项 */
curl_easy_setopt(easy_handle, CURLOPT_NOSIGNAL, 1L); // 禁用信号,提高线程安全性
curl_easy_setopt(easy_handle, CURLOPT_DNS_CACHE_TIMEOUT, 60); // DNS缓存60秒
curl_easy_setopt(easy_handle, CURLOPT_TIMEOUT_MS, 10*1000); // 总超时10秒
curl_easy_setopt(easy_handle, CURLOPT_CONNECTTIMEOUT_MS, 10*1000); // 连接超时10秒
/* 步骤7: 设置回调函数 */
curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, callbackfun); // 响应数据处理回调
/* 步骤8: 设置写入数据目标 */
if (writedata != NULL)
{
curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, writedata); // 回调函数的数据参数
}
/* 步骤9: 执行HTTP请求(核心操作) */
return_code = curl_easy_perform(easy_handle);
if(return_code != 0)
{
printf("url[%s] code[%d]\n", urlforsend, return_code); // 请求失败日志
ret = return_code; // 记录错误码
}
/* 步骤10: 清理资源 */
curl_slist_free_all(headers); // 释放HTTP头部链表
curl_easy_cleanup(easy_handle); // 清理CURL句柄
return ret; // 返回操作结果
}
Makefile
# 包含上级目录的通用Makefile参数配置
# 架构思想:使用统一的编译配置,确保项目编译标准一致性
include ../../Makefile.param
# 定义库名称,体现模块化设计思想
# 架构分析:每个模块有明确的命名标识,便于依赖管理
LIB_NAME := curlmsg
#************************************ PATH *************************************
# 头文件目录配置
# 系统源码树形结构:inc/ -> 模块公共头文件
INC_DIR := inc
# 注释掉的可选头文件路径,显示模块的可扩展性
#INC_DIR += inc/openssl/
#INC_DIR += inc/curl/
# 源代码目录
# 系统源码树形结构:src/ -> 模块实现文件
SRC_DIR := src
# 库文件输出目录,指向上级lib目录
# 架构思想:统一的库文件管理,便于其他模块链接
LIB_DIR := ../lib
# 二进制输出目录
BIN_DIR := bin
# 自动获取根目录路径的复杂Makefile技巧
# 设计思想:实现路径无关的编译,增强Makefile可移植性
ROOT_PATH:=$(abspath $(lastword $(MAKEFILE_LIST)))
ROOT_PATH:=$(shell dirname $(ROOT_PATH))
#************************************ COMPILE CONFIG *************************************
# 交叉编译工具链配置
# 系统设计:支持跨平台编译,体现嵌入式系统开发特点
CC := $(CROSS)gcc
AR := $(CROSS)ar
# 编译标志配置
# 性能分析:-O3优化级别,-rdynamic支持动态链接,-pthread多线程支持
CFLAGS = -Wall -O3 -rdynamic -g3 -pthread
# 添加平台特定编译标志,体现分层架构思想
CFLAGS += $(PLATFORM_CFLAGS)
# 源代码文件自动发现
# 架构优点:自动处理src目录下所有.c文件,支持模块扩展
SRCS := $(wildcard $(SRC_DIR)/*.c)
# 对象文件生成规则:将.c文件转换为.o文件
OBJS := $(SRCS:%.c=%.o)
# 测试相关配置(当前被注释)
TEST_SRCS := $(wildcard $(TEST_DIR)/*.c)
TEST_OBJS := $(patsubst %.c, %.o, $(TEST_SRCS))
# 头文件包含路径配置
# 系统源码树形结构:清晰的依赖关系管理
INC_FLAG := -I $(INC_DIR)
# 第三方库头文件路径,显示模块的外部依赖
INC_FLAG += -I inc/openssl/
INC_FLAG += -I inc/curl/
# 注释掉的系统公共头文件路径,体现模块间依赖关系
#INC_FLAG += -I $(ROOT_PATH)/interface/sys_common/inc
# 库依赖配置(当前被注释)
#LIBS := $(ROOT_PATH)/interface/lib/sys_common.a
#LIBS += XXXX(依赖的库文件)
# 输出目标定义
# 架构思想:明确的输出目标管理
OBJ_LIB := $(LIB_DIR)/lib$(LIB_NAME).a # 静态库输出路径
OBJ_TEST := bin/$(LIB_NAME)_test # 测试程序输出路径
# 编译命令模板
# 设计模式:模板方法模式,定义标准的编译过程
COMPILE = $(CC) $(CFLAGS) -c $< -o $@ $(INC_FLAG)
# 链接命令模板
LINK_LIB = $(AR) -r $@ $^ # 静态库打包命令
LINK = $(CC) $(CFLAGS) $^ $(LIBS) -o $@ $(INC_FLAG) # 可执行文件链接命令
#************************************ COMPILE *************************************
# 默认构建目标
# 架构思想:库优先的构建策略,体现模块化开发理念
all: $(OBJ_LIB)
# $(OBJ_TEST) # 测试目标被注释,需要时启用
# 静态库构建规则
# 软件设计:分离编译和链接阶段,提高构建效率
$(OBJ_LIB): $(OBJS)
@echo ===================================
@echo make $(LIB_NAME) lib
@$(LINK_LIB) # 执行静态库打包
@echo ===================================
# 测试程序构建规则(当前被注释)
$(OBJ_TEST): $(TEST_OBJS)
@echo ===================================
@echo make $(LIB_NAME) test
@$(LINK) # 链接测试程序
@echo ===================================
# 通用编译规则:将.c文件编译为.o文件
# 设计模式:模式规则,处理所有.c文件的编译
%.o :%.c
@$(COMPILE) # 执行编译命令
# 清理规则
# 系统管理:完整的清理功能,确保干净的重建
clean:
@echo ===================================
@echo clean $(LIB_NAME)
@rm -f $(OBJS) $(OBJ_LIB) $(OBJ_TEST) # 删除所有生成文件
@echo ===================================
架构分析报告
一、模块架构思想树形结构
curlmsg模块架构 ├── 头文件层 (inc/) │ ├── 模块自有头文件 │ ├── openssl依赖头文件 │ └── curl依赖头文件 ├── 实现层 (src/) │ └── *.c 源文件 ├── 输出层 │ ├── 静态库 (../lib/libcurlmsg.a) │ └── 测试程序 (bin/curlmsg_test) └── 配置层 ├── 本地配置 (Makefile) └── 全局配置 (../../Makefile.param)
二、软件设计系统源码树形结构
项目根目录/ ├── 当前模块 (curlmsg/) │ ├── inc/ # 模块头文件 │ ├── src/ # 模块实现 │ ├── Makefile # 模块构建配置 │ └── (生成的bin/, 依赖的../lib/) ├── 其他模块1/ ├── 其他模块2/ ├── lib/ # 全局库目录 │ └── libcurlmsg.a # 本模块输出 ├── interface/ │ ├── sys_common/ # 系统公共模块 │ └── ...其他接口模块 └── 全局配置/ └── Makefile.param # 统一编译参数
三、设计理念分析
-
模块化设计
-
清晰的边界:每个模块独立编译为静态库
-
明确的依赖:通过INC_FLAG管理头文件依赖
-
统一的输出:所有库文件集中到../lib目录
-
-
可配置性
-
平台无关:通过PLATFORM_CFLAGS支持多平台
-
交叉编译:支持CROSS编译工具链
-
灵活扩展:注释部分显示模块的可扩展性
-
-
构建效率
-
增量编译:只重新编译改变的源文件
-
并行构建:支持make -j并行编译
-
清晰输出:详细的构建过程提示
-
-
质量保证
-
调试支持:-g3调试信息
-
警告严格:-Wall显示所有警告
-
性能优化:-O3优化级别
-
四、改进建议
-
当前限制
-
测试框架被注释,缺乏自动化测试
-
外部依赖管理不够明确
-
缺乏安装和部署规则
-
-
扩展方向
-
添加共享库构建支持
-
集成单元测试框架
-
增加版本管理支持
-
更多推荐


所有评论(0)