news 2026/9/10 2:07:29

curl 库 CURLINFO_SIZE_UPLOAD_T 完全指南:精确统计上传字节数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
curl 库 CURLINFO_SIZE_UPLOAD_T 完全指南:精确统计上传字节数

curl 库 CURLINFO_SIZE_UPLOAD_T 完全指南:精确统计上传字节数

【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl

导读

CURLINFO_SIZE_UPLOAD_T是 libcurl 提供的运行时统计接口,用于在请求完成后读取本次传输实际上传的总字节数。它在 curl 项目(GitHub_Trending/cu/curl)中广泛应用于进度展示、限速与断点续传等场景——无论是用curl_easy_perform完成的一次性上传,还是基于curl_multi的并发上传任务,都能通过它拿到精确的curl_off_t类型计数。读完本文,你将掌握该选项的完整用法、与旧版CURLINFO_SIZE_UPLOAD的区别、底层数据来源,以及如何在真实代码中正确获取与格式化上传字节数。

接口速览

函数原型

#include <curl/curl.h> CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_SIZE_UPLOAD_T, curl_off_t *uploadp);
  • handle:已初始化并完成一次curl_easy_perform(或 multi 接口驱动)传输的 easy handle。
  • uploadp:指向curl_off_t的指针,函数执行成功后,此处写入本次传输累计上传的字节总数。
  • 返回值:CURLcode状态码,CURLE_OK表示成功,非零表示出错(具体错误参见 libcurl-errors)。

类型定义(头文件中的枚举值)

在 include/curl/curl.h 中可以看到该选项在CURLINFO枚举中的定义:

CURLINFO_SIZE_UPLOAD CURL_DEPRECATED(7.55.0, "Use CURLINFO_SIZE_UPLOAD_T") = CURLINFO_DOUBLE + 7, CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7,

其中CURLINFO_OFF_T0x600000)是 64 位有符号整数类型的标记位,CURLINFO_DOUBLE0x300000)是双精度浮点标记位。这从编译期就决定了新旧两个选项的输出数据类型不同:旧版CURLINFO_SIZE_UPLOAD返回double,新版CURLINFO_SIZE_UPLOAD_T返回curl_off_tCURL_DEPRECATED(7.55.0, ...)宏表明旧接口自 7.55.0 起被标记为废弃,官方建议一律改用_T后缀版本。

基本用法:读取上传字节数

以下代码完整演示了获取上传字节数的标准流程,示例同时用于 PUT/POST 等上传场景:

#include <stdio.h> #include <curl/curl.h> int main(void) { CURL *curl = curl_easy_init(); if(curl) { CURLcode result; curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); /* Perform the request */ result = curl_easy_perform(curl); if(result == CURLE_OK) { curl_off_t ul; result = curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD_T, &ul); if(result == CURLE_OK) { printf("Uploaded %" CURL_FORMAT_CURL_OFF_T " bytes\n", ul); } } curl_easy_cleanup(curl); } return 0; }

要点说明:

  • 调用时机:必须在该 easy handle 完成传输之后(例如curl_easy_perform返回之后)调用,否则读到的仍是上一次或未初始化的值。在 multi 接口中,应在CURLMSG_DONE消息回调或curl_multi_info_read返回该 transfer 完成状态之后再查询。
  • 返回值检查curl_easy_getinfo的返回值同样需要检查,即使perform成功,getinfo 也可能因参数类型不匹配等原因返回错误。
  • 类型与格式化curl_off_t通常是 64 位有符号整数,不能直接用%d/%ld打印(不同平台宽度可能不同),应使用头文件提供的CURL_FORMAT_CURL_OFF_T格式化宏以保证可移植性。
  • 计数语义:统计的是“实际上传”的字节数,即写入协议的数据量;对 HTTP 而言包括请求体(如 PUT/POST 的 body)等上行数据,但不包括协议头(header)部分。该值遵循CURLINFO_OFF_T类型,可表示超大文件的上传量而不受double精度损失影响。

与 CURLINFO_SIZE_UPLOAD(旧版)的对比

对比项CURLINFO_SIZE_UPLOAD(废弃)CURLINFO_SIZE_UPLOAD_T(推荐)
引入版本7.4.17.55.0
输出类型double *curl_off_t *
精度大数(如超过 2^53 字节)存在精度损失64 位整数,无损
状态自 7.55.0 起CURL_DEPRECATED当前推荐接口

旧版定义参见 docs/libcurl/opts/CURLINFO_SIZE_UPLOAD.md,其内部实现*param_doublep = (double)data->progress.ul.cur_size;(见 lib/getinfo.c)会将 64 位计数强转成double,当上传量超过double精确表示范围(约 9 PB)时不再精确;新版则直接返回data->progress.ul.cur_size的原始curl_off_t值(见 lib/getinfo.c)。因此凡是上传量可能很大的场景,都应使用_T版本。

底层实现:数据从哪来

CURLINFO_SIZE_UPLOAD_T不是独立维护的计数器,而是直接读取 easy handle 内部进度结构体struct Progress中上传方向的累计值。整个数据链路如下:

  1. 存储位置struct Progress内包含上传方向统计子结构struct pgrs_dir ul,其成员cur_size即“已传输字节数”(见 lib/urldata.h):
struct pgrs_dir { curl_off_t total_size; /* total expected bytes */ curl_off_t cur_size; /* transferred bytes so far */ curl_off_t speed; /* bytes per second transferred */ struct Curl_rlimit rlimit; /* speed limiting / pausing */ };
  1. 计数累加:传输过程中,各协议过滤器(filter)每写出delta字节,都会调用进度模块的Curl_pgrs_upload_inc()data->progress.ul.cur_size += delta(见 lib/progress.c);另有Curl_pgrsSetUploadCounter()用于直接设置当前上传计数值(见 lib/progress.c)。
  2. 读取返回curl_easy_getinfo内部在CURLINFO_SIZE_UPLOAD_T分支直接返回*param_offt =>curl_off_t sent, expected; curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD_T, &sent); curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_UPLOAD_T, &expected); if(expected >= 0 && sent != expected) fprintf(stderr, "Upload incomplete: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T " bytes\n", sent, expected);

    2. 配合上传选项使用

    CURLINFO_SIZE_UPLOAD_T通常与以下上传相关选项配合,构成完整的上传流程:

    • CURLOPT_UPLOAD:开启上传模式(如 FTP 上传、HTTP PUT)。
    • CURLOPT_POSTFIELDS/CURLOPT_POSTFIELDSIZE/CURLOPT_POSTFIELDSIZE_LARGE:指定 POST 数据及长度(_LARGE版本使用curl_off_t,与本文类型一致)。
    • CURLOPT_READFUNCTIONCURLOPT_READDATA:自定义上传数据读取回调。
    • CURLOPT_INFILESIZE_LARGE:告知服务器上传文件大小。
    • CURLOPT_RESUME_FROM_LARGE:断点续传偏移,配合续传完成后用本选项核对已传总量。

    各选项的详细说明见 docs/libcurl/opts 目录,例如CURLOPT_UPLOAD.mdCURLOPT_INFILESIZE_LARGE.md

    3. 在 multi 接口中统计并发上传

    在多句柄并发场景下,每个 easy handle 独立维护自己的ul.cur_size,因此可在每个 transfer 完成(CURLMSG_DONE)后分别查询,再汇总得到整体上传量,互不干扰。

    注意事项与易错点

    1. 必须在传输完成后读取:传输进行中读取可能得到 0 或中间值;重用一个 easy handle 发起第二次传输前,值会在新传输初始化时被清零(见 lib/progress.c)。
    2. 类型必须匹配_T版本必须传入curl_off_t *,旧版必须传入double *。混用会导致内存越界写入(类型大小不同),属于未定义行为。
    3. 统计范围是“已发送的应用数据”:不包含协议头;对分块传输(chunked)等场景,计数的是 payload 字节。
    4. 旧版精度问题:不要在新代码中使用CURLINFO_SIZE_UPLOAD;即使旧代码,也建议迁移到_T版本。
    5. 版本要求:该接口自 libcurl 7.55.0 引入(见文档头部Added-in: 7.55.0字段),使用前需确认链接的 libcurl 版本满足要求。

    小结

    CURLINFO_SIZE_UPLOAD_T是 libcurl 获取上传字节数的事实标准接口:它以 64 位整数精确返回每次传输的上传总量,底层直接读取进度模块ul.cur_size计数器,与速率、长度等_T系列接口协同可完整刻画上传过程。在实践中记住三点即可用得准确:传输完成后查询、传curl_off_t *、用CURL_FORMAT_CURL_OFF_T打印。更多细节可参考 docs/libcurl/opts/CURLINFO_SIZE_UPLOAD_T.md 与配套的 curl_easy_getinfo 文档。

    【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 2:06:49

语音情感识别实战:基于PyTorch的CNN+LSTM模型构建与部署

简介&#xff1a;基于Pytorch实现的语音情感识别项目源码&#xff0c;面向机器学习开发者与语音技术研究人员&#xff0c;提供从语音降噪、特征提取到模型训练与推理的完整流程&#xff0c;适用于智能客服、心理健康辅助、人机交互等场景。压缩包共29个文件&#xff0c;包含25个…

作者头像 李华
网站建设 2026/9/10 2:04:34

CANN/GE算子表达样例指南

Graph中各类算子表达样例 【免费下载链接】ge GE&#xff08;Graph Engine&#xff09;是面向昇腾的图编译器和执行器&#xff0c;提供了计算图优化、多流并行、内存复用和模型下沉等技术手段&#xff0c;加速模型执行效率&#xff0c;减少模型内存占用。 GE 提供对 PyTorch、T…

作者头像 李华
网站建设 2026/9/10 2:00:48

树莓派4B部署YOLOv5-Lite目标检测:从模型转换到NCNN推理实战

简介&#xff1a;面向树莓派4B的YOLOv5-Lite目标检测资源包&#xff0c;为边缘计算与IoT场景提供了一套轻量级深度学习落地方案&#xff0c;适合希望在低功耗设备上完成实时目标检测的开发者、学习者&#xff0c;可应用于智能安防、无人零售、农业监测等常见边缘视觉任务。资源…

作者头像 李华
网站建设 2026/9/10 2:00:21

Ruffle拖放SWF完整内幕:丢进窗口的那0.5秒里,后台跑了4次接力

Ruffle拖放SWF完整内幕:丢进窗口的那0.5秒里,后台跑了4次接力 【免费下载链接】ruffle A Flash Player emulator written in Rust 项目地址: https://gitcode.com/GitHub_Trending/ru/ruffle 把 game.swf 拖进窗口、松开鼠标,半秒后画面就动起来了。Ruffle 的拖放加载看…

作者头像 李华
网站建设 2026/9/10 2:00:19

CANN/ge AddNodeByOp API文档

AddNodeByOp 【免费下载链接】ge GE&#xff08;Graph Engine&#xff09;是面向昇腾的图编译器和执行器&#xff0c;提供了计算图优化、多流并行、内存复用和模型下沉等技术手段&#xff0c;加速模型执行效率&#xff0c;减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前…

作者头像 李华
网站建设 2026/9/10 2:00:02

涡板块法计算二维翼型:从物理原理到代码实战

简介&#xff1a;针对空气动力学课程中二维翼型气动力计算的需求&#xff0c;这份资料围绕涡板块法提供了一套可供课程大作业直接使用的Matlab实现。源码按功能拆分多个脚本&#xff0c;包含主程序、涡强求解函数、翼型坐标生成函数&#xff0c;并额外提供GPU加速版本&#xff…

作者头像 李华