libcurl是跨平台文件下载最可靠的方案,支持HTTPS、断点续传、超时控制;需正确初始化/清理、自定义WRITEFUNCTION回调、配置SSL验证与TLS版本,并设置超时及进度回调以保障大文件下载稳定性。

用 libcurl 下载文件最可靠,Windows/macOS/Linux 都能跑
标准 C++ 没有内置网络下载能力,libcurl 是事实上的首选——它稳定、支持 HTTPS、断点续传、超时控制,而且跨平台。别碰 std::filesystem 或 std::fstream 单独组合 HTTP 请求,那是在重复造轮子且大概率出错。
实操建议:
- Windows 上用 vcpkg 安装:
vcpkg install curl:x64-windows;macOS 用 Homebrew:brew install curl;Linux 用 apt/yum 安装libcurl4-openssl-dev或对应开发包 - 编译时必须链接
-lcurl(GCC/Clang)或在 VS 项目属性里添加libcurl.lib - 初始化一次
curl_global_init(CURL_GLOBAL_DEFAULT),程序退出前调用curl_global_cleanup(),否则可能内存泄漏或 DNS 缓存异常
CURLOPT_WRITEFUNCTION 必须自定义,否则文件内容会丢
默认情况下 libcurl 把响应体输出到 stdout,不写磁盘。想保存成文件,必须用 CURLOPT_WRITEFUNCTION 指定回调函数,并通过 CURLOPT_WRITEDATA 传入 FILE* 指针。
常见错误现象:程序运行无报错,但生成的文件是空的,或只有一小段乱码——大概率是回调函数没正确返回接收字节数,或 WRITEDATA 传了野指针。
立即学习“C++免费学习笔记(深入)”;
关键点:
- 回调函数签名必须是
size_t write_callback(void* ptr, size_t size, size_t nmemb, void* userdata) - 返回值必须是
size * nmemb(即实际写入字节数),返回 0 会让 libcurl 中止传输 -
userdata通常传FILE*,用fwrite(ptr, 1, size * nmemb, static_cast<file>(userdata))</file>写入,别用fprintf
HTTPS 下载失败?检查证书验证和协议版本
很多新手遇到 CURLE_SSL_CACERT 或 CURLE_UNSUPPORTED_PROTOCOL 错误,本质是 libcurl 编译时没绑定 OpenSSL(或 macOS 上用了 SecureTransport),导致无法校验证书或协商 TLS 版本。
使用场景:内网测试可临时跳过证书验证,但生产环境绝不能留着 CURLOPT_SSL_VERIFYPEER 和 CURLOPT_SSL_VERIFYHOST 设为 0L 的代码。
安全又实用的做法:
- Linux/macOS:确保系统 CA 证书路径正确,用
CURLOPT_CAINFO显式指定(如/etc/ssl/certs/ca-certificates.crt) - Windows:vcpkg 安装的 curl 默认带 OpenSSL,但需确认是否启用了
ssl特性(vcpkg install curl[ssl]:x64-windows) - 强制 TLS 1.2+:
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2)
大文件下载要设超时和进度回调,不然卡死没人知道
下载几百 MB 文件时,若网络抖动或服务器响应慢,curl_easy_perform() 可能卡住几十秒甚至更久,默认超时是 0(无限等待)。用户感知就是“程序假死”。
性能与体验兼顾的设置:
-
CURLOPT_TIMEOUT控制总耗时(单位秒),CURLOPT_CONNECTTIMEOUT控制建连阶段(推荐 10–30 秒) - 用
CURLOPT_XFERINFOFUNCTION注册进度回调,配合CURLOPT_NOPROGRESS设为 0L 启用——注意该回调不是每字节触发,而是大约每秒数次,适合更新 UI 或日志 - 避免在回调里做耗时操作(如频繁写磁盘日志),否则反而拖慢下载
真正难处理的是断网重连和断点续传:需要先用 HEAD 请求获取 Content-Length 和 Accept-Ranges,再用 CURLOPT_RESUME_FROM 接续。这部分逻辑容易被忽略,但对大文件稳定性至关重要。


















