最简http下载应直接用libcurl:设curlopt_url、curlopt_writefunction、curlopt_writedata、curlopt_followlocation和curlopt_timeout,回调返回实际写入字节数,避免空文件或崩溃;https需确认openssl支持,大文件须流式写盘,进度反馈推荐curlopt_xferinfofunction。

用 libcurl 实现基础 HTTP 下载,别自己解析 HTTP 协议
自己手写 socket + 解析 HTTP 响应头 + 处理重定向 + 管理连接,99% 的场景纯属重复造轮子,还容易出错。直接用 libcurl 是最稳妥的选择——它已处理了 TLS、重定向、断点续传、代理、超时等所有边界情况。
安装时注意:Windows 下推荐用 vcpkg:vcpkg install curl;macOS 用 brew install curl;Linux 通常自带 libcurl4-openssl-dev(Ubuntu/Debian)或 libcurl-devel(CentOS/RHEL)。
链接时确保加 -lcurl(g++/clang++),Windows MSVC 需链接 curldll.lib 或静态版 libcurl.lib。
最简下载代码:只关注 curl_easy_perform 和回调函数
核心不是“发起请求”,而是“把响应体写到哪”。必须设置 CURLOPT_WRITEFUNCTION 和 CURLOPT_WRITEDATA,否则下载内容会直接丢弃或输出到 stdout(默认行为)。
-
CURLOPT_URL:填目标 URL 字符串(const char*),支持http://和https:// -
CURLOPT_WRITEFUNCTION:设为自定义回调函数,每次收到数据块就调用一次 -
CURLOPT_WRITEDATA:传入一个FILE*或std::vector<uint8_t>*</uint8_t>指针,供回调函数写入 -
CURLOPT_FOLLOWLOCATION:设为1L才能自动处理 301/302 重定向 -
CURLOPT_TIMEOUT:建议设为30L(秒),避免卡死
示例回调(写入文件):
size_t write_callback(void* ptr, size_t size, size_t nmemb, void* userdata) {
FILE* fp = static_cast<file>(userdata);
size_t written = fwrite(ptr, size, nmemb, fp);
return written;
}</file>
调用时:curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); —— fp 必须是已打开的 "wb" 模式文件指针。
常见错误:下载空文件、乱码、崩溃
空文件基本等于没设 CURLOPT_WRITEFUNCTION 或回调返回值不对;乱码通常是二进制内容被当文本读取;崩溃多因 WRITEDATA 指针悬空或未初始化。
- 回调函数返回值必须是实际写入字节数(
size * nmemb),不能硬写nmemb或1,否则 libcurl 会认为写失败并中止下载 - 不要在回调里调用
fclose(fp)——fp生命周期必须覆盖整个curl_easy_perform调用 - HTTPS 下载失败?检查是否链接了 OpenSSL 或 Schannel(Windows)后端,
curl_version()可确认协议支持 - 下载大文件时内存暴增?别把全部数据存
std::string再写盘,用流式回调直接写文件
需要进度反馈?用 CURLOPT_XFERINFOFUNCTION 替代过时的 PROGRESSFUNCTION
libcurl 7.32.0+ 推荐用 CURLOPT_XFERINFOFUNCTION,它更可靠且支持 64 位大小。旧版 PROGRESSFUNCTION 在大文件下会溢出。
关键点:
- 必须同时设
CURLOPT_XFERINFODATA(用户数据指针)和CURLOPT_NOPROGRESS为0L - 回调原型:
int xfer_info(void* userdata, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) -
dltotal和dlnow是已下载字节数和总大小(可能为 -1 表示未知) - 返回非零值会中止传输,可用于实现取消逻辑
注意:进度回调不是高频触发的,别在里面做耗时操作(如 printf),否则拖慢下载。
真正麻烦的从来不是“怎么开始下载”,而是“如何安全终止、恢复、校验、并发控制”——这些要等需求明确后再加,别一上来就堆功能。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











