不推荐用C++标准库直接发HTTP请求,因其无内置HTTP客户端支持,std::net尚未稳定落地,手写socket易出错;libcurl是跨平台事实标准,支持HTTPS/代理/超时等,但需正确链接、调用curl_global_init、检查返回值并避免CURLOPT_FAILONERROR默认关闭导致404误判。

不推荐用C++标准库直接发HTTP请求
C++标准库没有内置HTTP客户端支持,std::net(C++23草案中的网络库)尚未稳定落地,主流编译器基本不支持。硬靠socket手写HTTP协议容易出错:状态码解析漏、header换行符不对、chunked编码没处理、连接复用没管理——轻则返回空响应,重则被服务器静默断连。
用libcurl最稳妥,但要注意链接方式和错误检查
libcurl是事实标准,跨平台、成熟、支持HTTPS/代理/重试/超时。关键不是“能不能用”,而是“怎么避免常见崩点”:
- Linux下编译必须加
-lcurl,且确保安装的是libcurl4-openssl-dev(Ubuntu)或curl-devel(CentOS),只装curl命令行工具不够 - Windows下用vcpkg安装后,链接时要确认
curldll.lib或libcurl.lib路径正确,否则unresolved external symbol curl_easy_init - 每次调用
curl_easy_perform后必须检查返回值:CURLE_OK才表示成功;CURLE_COULDNT_CONNECT和CURLE_HTTP_RETURNED_ERROR含义不同,后者说明已连上但HTTP状态码非2xx - 别忘了调用
curl_global_init(CURL_GLOBAL_DEFAULT)一次(通常在main开头),否则Windows下可能崩溃
// 简单GET示例(含基础错误检查)
CURL* curl = curl_easy_init();
if (!curl) return -1;
curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/get");
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}
curl_easy_cleanup(curl);
如果项目不能引入第三方库,考虑用系统命令临时绕过
极端受限环境(如嵌入式裸机无包管理)下,可调用系统curl/wget命令,但仅限调试或原型验证,不可用于生产:
-
std::system("curl -s -o /tmp/out.json https://api.example.com/data")—— 注意-s静默输出,否则stderr会干扰终端 - 用
popen()捕获响应体更安全,但需手动处理进程退出码和信号(WEXITSTATUS),且无法设置超时或证书校验 - Windows下
curl.exe不一定存在,得fallback到PowerShell Invoke-RestMethod,路径和引号转义极易出错
异步场景别碰libcurl默认接口,改用multi接口或换库
curl_easy_perform是阻塞的,主线程卡死。想并发10个请求,不是开10个线程各跑一个easy handle——那样资源浪费且难管理。正确做法是:
立即学习“C++免费学习笔记(深入)”;
- 用
curl_multi_*系列函数(curl_multi_init、curl_multi_add_handle),配合select()轮询fd集合,适合中等并发(几十路) - 高并发(百级以上)或需要与event loop集成时,优先选
Boost.Beast(基于ASIO,需C++17+)或cpp-httplib(头文件库,自带server/client,但不支持HTTP/2) - 注意
cpp-httplib默认禁用SSL,启用需定义CPPHTTPLIB_OPENSSL_SUPPORT并链接-lssl -lcrypto,否则https://地址会直接失败
实际用的时候,90%的case用libcurl + 同步easy接口就够了,但务必检查CURLOPT_FAILONERROR是否开启(默认关),不然404也会返回CURLE_OK——这个坑很多人第一次就踩。


















