使用 libcurl 发起 HTTP 请求是 C++ 生产环境的标准方案,需正确初始化全局环境、设置 URL 和回调函数、检查返回值、配置超时与 SSL 选项,并注意 Windows 下运行时和 SSL 后端匹配。

用 libcurl 发起 GET 请求是最直接的方案
标准 C++ 没有内置 HTTP 客户端,硬写 socket + HTTP 协议解析既容易出错又无必要。生产环境几乎都用 libcurl——它稳定、跨平台、支持 HTTPS、自动处理重定向和 Cookie 等细节。
常见错误是只链接 libcurl 但没初始化全局环境,导致首次请求卡死或崩溃。必须在程序开始时调用 curl_global_init(CURL_GLOBAL_DEFAULT),结束前调用 curl_global_cleanup()。
示例关键步骤:
- 调用
curl_easy_init()获取句柄 - 用
curl_easy_setopt(handle, CURLOPT_URL, "https://httpbin.org/get")设置目标 URL - 用
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback)指定数据接收回调(不能用std::string成员函数作回调,得是自由函数或 static 成员) - 调用
curl_easy_perform()执行,返回值为CURLE_OK才算成功
POST 请求要手动设置 CURLOPT_POSTFIELDS 或 CURLOPT_HTTPPOST
CURLOPT_POSTFIELDS 最适合发送纯文本 body(如 JSON),但注意:它会自动添加 Content-Type: application/x-www-form-urlencoded,如果发 JSON,必须显式覆盖:curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers),其中 headers 是 struct curl_slist*,包含 "Content-Type: application/json"。
立即学习“C++免费学习笔记(深入)”;
若需上传文件或混合字段(如表单含文件+文本),必须用 CURLOPT_HTTPPOST 配合 curl_httppost 相关 API,否则字段会被忽略或编码错误。
容易踩的坑:
- 传入的 POST 数据指针生命周期必须长于
curl_easy_perform()调用——不能传局部std::string::c_str()的结果,除非确保 string 不析构 - 未检查
curl_easy_perform()返回值,把网络超时、DNS 失败等当成功处理 - 忽略 HTTPS 证书验证:开发时可设
CURLOPT_SSL_VERIFYPEER为 0L,但上线必须恢复默认(1L)并配好 CA 证书路径
同步阻塞是默认行为,别误以为“C++ 没法做 HTTP”
有人试过原生 socket 写 HTTP,发现连不上或收不到响应,就以为 C++ 不适合发 HTTP 请求——其实只是没正确处理 TCP 连接建立、HTTP 响应头解析、分块传输(chunked encoding)或 keep-alive 等细节。libcurl 默认就是同步阻塞调用,行为和 Python 的 requests.get() 几乎一致,学习成本很低。
真正要注意的是超时控制:CURLOPT_TIMEOUT 控制总耗时,CURLOPT_CONNECTTIMEOUT 控制连接阶段,两者都该设(比如分别设为 10L 和 5L),否则 DNS 卡住或服务器不响应时程序会无限等待。
其他实用配置:
-
CURLOPT_FOLLOWLOCATION设为 1L 自动跟随 302 重定向 -
CURLOPT_USERAGENT设为自定义字符串,避免被服务端拦截(某些 API 拒绝空 UA) -
CURLOPT_VERBOSE设为 1L 查看完整请求/响应过程,调试时开,上线前关
Windows 下链接 libcurl 需注意运行时和 SSL 后端
Windows 用户最容易卡在这步:下载预编译库时选错版本。必须匹配三要素:Visual Studio 版本(如 v143)、运行时类型(/MD 还是 /MT)、SSL 后端(Schannel 还是 OpenSSL)。混用会导致链接失败或运行时报 LNK2019、Access violation。
推荐做法:
- 用 vcpkg 安装:
vcpkg install curl:x64-windows,它自动处理依赖和链接选项 - 若手动集成,优先选 Schannel(Windows 自带),避免额外部署 OpenSSL DLL;对应链接库名通常是
libcurl.lib(非curldll.lib) - 确认项目属性中 “C/C++ → 代码生成 → 运行时库” 和 libcurl 编译时一致(如都是
/MD)
HTTPS 请求失败却没报错?大概率是 SSL 后端没加载成功,加一句 curl_version_info(CURLVERSION_NOW)->features & CURL_VERSION_SSL 判断是否启用了 SSL 支持。











