掌握libcurl:从GET请求到HTTPS验证全解析
1. 初始化 libcurl在程序开始时调用一次#includestdio.h#includecurl/curl.hintmain(void){CURLcode res;rescurl_global_init(CURL_GLOBAL_DEFAULT);if(res!CURLE_OK){fprintf(stderr,curl_global_init failed: %s\n,curl_easy_strerror(res));return1;}// 后续执行网络请求curl_global_cleanup();return0;}注意curl_global_init()通常只需要调用一次。curl_global_cleanup()应该在程序结束时调用。如果程序中有多个CURL *对象也不应该重复调用全局初始化和清理函数。2. 创建 CURL 对象CURL*curlcurl_easy_init();if(curlNULL){fprintf(stderr,curl_easy_init failed\n);curl_global_cleanup();return1;}curl_easy_init()用于创建一个 easy handle也就是一次请求的控制对象。使用完成后必须调用curl_easy_cleanup(curl);3. 设置请求 URLconstchar*urlhttps://example.com;CURLcode rescurl_easy_setopt(curl,CURLOPT_URL,url);if(res!CURLE_OK){fprintf(stderr,CURLOPT_URL failed: %s\n,curl_easy_strerror(res));}也可以直接写成curl_easy_setopt(curl,CURLOPT_URL,https://example.com);curl_easy_setopt 的返回值curl_easy_setopt的函数形式是CURLcodecurl_easy_setopt(CURL*handle,CURLoption option,...);它返回一个CURLcode用于表示设置是否成功。常见的错误检查方式#defineCHECK_CURL(expr)\do{\CURLcode code(expr);\if(code!CURLE_OK){\fprintf(stderr,%s failed: %s\n,\#expr,curl_easy_strerror(code));\}\}while(0)4. 设置响应数据的处理函数libcurl 接收到服务器响应数据后会调用回调函数。回调函数原型为size_twrite_callback(char*ptr,size_tsize,size_tnmemb,void*userdata);参数说明参数含义ptr接收到的数据size每个数据单元的大小nmemb数据单元数量userdata用户自定义参数返回值实际处理的数据字节数实际数据长度为size * nmemb重要注意ptr指向的数据不一定以\0结尾不能直接当作 C 字符串使用可能包含二进制数据回调函数返回值必须表示已经处理的字节数。5. 将响应数据写入文件下面的回调函数可以将数据写入文件#includestdio.hsize_twrite_callback(char*ptr,size_tsize,size_tnmemb,void*userdata){FILE*fp(FILE*)userdata;returnfwrite(ptr,size,nmemb,fp)*size;}设置回调函数FILE*fpfopen(response.html,wb);if(fpNULL){perror(fopen);curl_easy_cleanup(curl);curl_global_cleanup();return1;}curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_callback);curl_easy_setopt(curl,CURLOPT_WRITEDATA,fp);这里CURLOPT_WRITEFUNCTION用于设置响应数据回调函数CURLOPT_WRITEDATA用于设置传递给回调函数的 userdata 参数。因此下面两项是配套使用的curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_callback);curl_easy_setopt(curl,CURLOPT_WRITEDATA,fp);回调函数被调用时userdata fp6. 将响应数据直接输出到标准输出如果想把服务器响应直接打印到终端curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_callback);curl_easy_setopt(curl,CURLOPT_WRITEDATA,stdout);也可以不设置CURLOPT_WRITEFUNCTIONlibcurl 默认会把响应写到标准输出。但显式设置更容易理解和控制。7. 执行网络请求CURLcode rescurl_easy_perform(curl);if(res!CURLE_OK){fprintf(stderr,curl_easy_perform failed: %s\n,curl_easy_strerror(res));}curl_easy_perform()会同步执行请求函数调用期间会阻塞当前线程接收到响应数据时会调用CURLOPT_WRITEFUNCTION设置的回调函数请求完成后才会返回。常见错误码错误码含义CURLE_OK操作成功CURLE_UNSUPPORTED_PROTOCOL不支持的协议CURLE_COULDNT_CONNECT无法连接服务器CURLE_OPERATION_TIMEDOUT请求超时CURLE_HTTP_RETURNED_ERRORHTTP 错误通常需要配合选项CURLE_SSL_CONNECT_ERRORSSL 连接错误8. 设置常用选项设置超时时间curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT,10L);curl_easy_setopt(curl,CURLOPT_TIMEOUT,30L);含义CURLOPT_CONNECTTIMEOUT连接服务器的最长时间CURLOPT_TIMEOUT整个请求允许的最长时间。跟随重定向服务器可能返回 301 或 302 重定向可以开启自动跟随curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1L);设置 User-Agentcurl_easy_setopt(curl,CURLOPT_USERAGENT,my-curl-client/1.0);设置 HTTPS 证书验证libcurl 默认会验证 HTTPS 证书建议保持默认配置curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,1L);curl_easy_setopt(curl,CURLOPT_SSL_VERIFYHOST,2L);不建议在生产环境中使用CURLOPT_SSL_VERIFYPEER0CURLOPT_SSL_VERIFYHOST0关闭验证会降低 HTTPS 的安全性只适合临时测试。9. 获取 HTTP 状态码curl_easy_perform()成功只代表网络层请求成功不一定代表 HTTP 返回码是 200。例如服务器可能返回200成功404资源不存在500服务器错误可以通过curl_easy_getinfo()获取 HTTP 状态码longresponse_code0;rescurl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,response_code);if(resCURLE_OK){printf(HTTP response code: %ld\n,response_code);}10. 一个完整的 GET 请求示例#includestdio.h#includecurl/curl.hstaticsize_twrite_callback(char*ptr,size_tsize,size_tnmemb,void*userdata){FILE*fp(FILE*)userdata;/* ptr 不一定是以 \0 结尾的字符串 必须按照 size 和 nmemb 指定的长度处理。 */returnfwrite(ptr,size,nmemb,fp)*size;}intmain(void){CURL*curlNULL;CURLcode res;longresponse_code0;rescurl_global_init(CURL_GLOBAL_DEFAULT);if(res!CURLE_OK){fprintf(stderr,curl_global_init failed: %s\n,curl_easy_strerror(res));return1;}curlcurl_easy_init();if(curlNULL){fprintf(stderr,curl_easy_init failed\n);curl_global_cleanup();return1;}FILE*fpfopen(response.html,wb);if(fpNULL){perror(fopen);curl_easy_cleanup(curl);curl_global_cleanup();return1;}rescurl_easy_setopt(curl,CURLOPT_URL,https://example.com);if(res!CURLE_OK){fprintf(stderr,set URL failed: %s\n,curl_easy_strerror(res));gotocleanup;}rescurl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_callback);if(res!CURLE_OK){fprintf(stderr,set write callback failed: %s\n,curl_easy_strerror(res));gotocleanup;}rescurl_easy_setopt(curl,CURLOPT_WRITEDATA,fp);if(res!CURLE_OK){fprintf(stderr,set write data failed: %s\n,curl_easy_strerror(res));gotocleanup;}curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1L);curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT,10L);curl_easy_setopt(curl,CURLOPT_TIMEOUT,30L);curl_easy_setopt(curl,CURLOPT_USERAGENT,my-curl-client/1.0);rescurl_easy_perform(curl);if(res!CURLE_OK){fprintf(stderr,request failed: %s\n,curl_easy_strerror(res));gotocleanup;}rescurl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,response_code);if(resCURLE_OK){printf(HTTP response code: %ld\n,response_code);}cleanup:fclose(fp);curl_easy_cleanup(curl);curl_global_cleanup();returnresCURLE_OK?0:1;}11. 编译程序Linux 下通常需要链接 libcurlgcc main.c-omain$(pkg-config--cflags--libslibcurl)也可以直接使用gcc main.c-omain-lcurl运行./main程序会请求https://example.com并将响应内容保存到response.html12. 将响应保存到内存如果不想写入文件而是想把响应内容保存到内存可以定义一个结构体#includestdlib.h#includestring.hstructMemory{char*data;size_tsize;};回调函数staticsize_tmemory_callback(char*ptr,size_tsize,size_tnmemb,void*userdata){size_ttotalsize*nmemb;structMemory*memory(structMemory*)userdata;char*new_datarealloc(memory-data,memory-sizetotal1);if(new_dataNULL){return0;}memory-datanew_data;memcpy(memory-datamemory-size,ptr,total);memory-sizetotal;memory-data[memory-size]\0;returntotal;}使用方式structMemorymemory{.dataNULL,.size0};curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,memory_callback);curl_easy_setopt(curl,CURLOPT_WRITEDATA,memory);CURLcode rescurl_easy_perform(curl);if(resCURLE_OK){printf(received %zu bytes\n,memory.size);printf(%s\n,memory.data);}free(memory.data);如果响应内容是二进制数据不应该使用%s输出而应该根据memory.size处理fwrite(memory.data,1,memory.size,stdout);13. 资源清理顺序基本清理顺序如下fclose(fp);curl_easy_cleanup(curl);curl_global_cleanup();如果不再使用 curl可以写curl_easy_cleanup(curl);curlNULL;但需要注意curl_easy_cleanup()之后不能再使用该 handlecurl_global_cleanup()应该在所有 easy handle 都清理之后调用free()、fclose()等用户自己创建的资源也要自行释放。14. 初学者容易犯的错误错误一没有检查 curl_easy_initCURL*curlcurl_easy_init();curl_easy_setopt(curl,...);如果初始化失败curl 可能为 NULL应该先判断。错误二把回调数据当作字符串错误示例printf(%s,ptr);ptr 不一定以\0结束正确做法是fwrite(ptr,1,size*nmemb,stdout);错误三忽略回调函数返回值如果回调函数返回的数据长度少于size * nmemblibcurl 通常会认为写入失败returntotal;错误四只判断 CURLcode不判断 HTTP 状态码curl_easy_perform(curl);返回CURLE_OK只说明请求过程完成仍然应该通过curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,response_code);检查 HTTP 状态码。错误五忘记设置超时默认情况下某些网络问题可能导致程序等待很长时间建议至少设置curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT,10L);curl_easy_setopt(curl,CURLOPT_TIMEOUT,30L);总结一个最基本的 libcurl 请求流程是curl_global_init(...);// 全局初始化curlcurl_easy_init();// 创建 CURL 对象curl_easy_setopt(...);// 设置 URL、回调等参数curl_easy_perform(curl);// 执行请求curl_easy_cleanup(curl);// 清理 CURL 对象curl_global_cleanup();// 全局清理响应数据处理的核心是curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,callback);curl_easy_setopt(curl,CURLOPT_WRITEDATA,userdata);其中CURLOPT_WRITEFUNCTION指定数据处理函数CURLOPT_WRITEDATA指定传给回调函数的用户参数回调函数必须按照size * nmemb处理数据返回值必须是实际处理的字节数。

相关新闻

基于二阶锥规划的主动配电网最优潮流求解(Matlab代码实现)

基于二阶锥规划的主动配电网最优潮流求解(Matlab代码实现)

👨‍🎓个人主页 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭:行百里者,半于九十。 📋&#x1f4…

2026/7/22 16:35:43 阅读更多 →
深入解析TI HDVPSS intc_intr1中断控制器:原理、配置与实战优化

深入解析TI HDVPSS intc_intr1中断控制器:原理、配置与实战优化

1. 项目概述在嵌入式视频处理系统的开发中,中断控制器就像是整个系统的“神经中枢”,它负责接收来自各个外设的“紧急呼叫”,并决定是否、以及何时通知CPU这个“大脑”去处理。今天,我们就来深入拆解德州仪器高清视频处理子系统中…

2026/7/22 16:35:43 阅读更多 →
中国电子多项AI创新成果入选国资央企人工智能典型案例

中国电子多项AI创新成果入选国资央企人工智能典型案例

2026世界人工智能大会(WAIC)期间,国务院国资委在“智赋新质 全域焕新”企业人工智能高质量发展论坛上正式启动“国资央企智能软件工厂联合筑基工程”,包括中国电子在内的首批13家中央企业研发力量参与共建。第二批央企人工智能战略…

2026/7/22 16:35:43 阅读更多 →

最新新闻

AI大模型与数学 第6课:导数定义、几何意义、导数四则运算、全套基本求导公式推导

AI大模型与数学 第6课:导数定义、几何意义、导数四则运算、全套基本求导公式推导

本课核心定位(AI最重要一课) 从这一课开始:数学真正进入AI训练核心。 课前说点我的感受,刚看到这的小伙伴或许有些困惑或疲惫,相信我继续看下去,我是看到第七八课左右开始有些开朗,看到十几课的…

2026/7/23 21:50:05 阅读更多 →
EUV 光源的工作机理

EUV 光源的工作机理

这张图是 EUV 光源系统的标准原理图,我按图上的标注,顺着光和锡的流动路径,把整个机理讲一遍。一、先看整体结构分三层图上从上到下分三层空间:Fab Floor(洁净厂房层)以上:主体是 Vessel&#x…

2026/7/23 21:50:05 阅读更多 →
伟肯 NXI00136 水冷制动单元

伟肯 NXI00136 水冷制动单元

伟肯 NXI00136 是 NX 系列水冷制动单元,适配共直流母线多传动系统。设备采用高效水冷散热方案,功率密度优异,有效节约柜体安装空间,无需布设专用通风风道,能够适应高粉尘、高湿度、空间局促的重工业现场。模块化结构可…

2026/7/23 21:50:05 阅读更多 →
Docker进阶——多容器编排和机器人仿真环境搭建

Docker进阶——多容器编排和机器人仿真环境搭建

面试翻车现场上篇讲了Docker基础,有读者问:"机器人系统那么复杂,一个容器够吗?"确实不够。一个完整的机器人系统通常包含多个组件:导航、感知、规划、控制、仿真器……每个组件都有各自的依赖。如果全塞进一…

2026/7/23 21:50:05 阅读更多 →
【RT-DETR涨点改进】TGRS 2026 | 卷积创新改进篇 | 引入 3DSBE 三维光谱瓶颈增强模块,增强模型对通道间互补信息的利用能力,助力高光谱目标检测、遥感目标检测任务,有效涨点

【RT-DETR涨点改进】TGRS 2026 | 卷积创新改进篇 | 引入 3DSBE 三维光谱瓶颈增强模块,增强模型对通道间互补信息的利用能力,助力高光谱目标检测、遥感目标检测任务,有效涨点

一、本文介绍 🔥本文给大家介绍使用 3DSBE 三维光谱瓶颈增强模块 改进RT-DETR网络模型,主要作用是在特征提取阶段强化不同通道或波段之间的相关性,减少冗余信息,并为后续多尺度融合提供更具判别力的特征表示。该模块通过空间下采样与通道扩展降低计算负担,再采用主、辅双…

2026/7/23 21:50:04 阅读更多 →
抖音团购如何进入豆包AI推荐答案:本地生活商家的GEO获客指南

抖音团购如何进入豆包AI推荐答案:本地生活商家的GEO获客指南

你有没有注意到,在豆包里搜索”北京适合聚餐的餐厅推荐”,排在最前面的答案里出现了某个抖音团购套餐的链接?或者在豆包问”周末带孩子去哪玩”时,推荐了一个本地商家的抖音团购链接,而你根本没有在任何搜索引擎上搜过…

2026/7/23 21:49:04 阅读更多 →

日新闻

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:25 阅读更多 →
AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

更多请点击: https://codechina.net 第一章:AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析 在对2,346篇跨行业AI生成文案的A/B测试数据进行聚类分析后,我们发现&#xff1…

2026/7/23 0:01:26 阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:01:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 8:58:19 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 19:43:43 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 17:49:47 阅读更多 →

月新闻