C++怎么发送HTTP请求 C++使用libcurl库进行网络通信【网络】

9次阅读

libcurlc++发送http请求最成熟跨平台方案;需全局初始化、设URL/超时、检查返回值;POST jsON须设header、body及长度;响应体用WRITEFUNCTION捕获,状态码用getinfo获取;https证书失败应配CA路径而非禁用验证。

C++怎么发送HTTP请求 C++使用libcurl库进行网络通信【网络】

直接用 libcurl 发送 HTTP 请求是 C++ 里最成熟、跨平台也最可控的方式;没有标准库支持,别试图手写 socket 拼 HTTP 报文。

初始化和基础 GET 请求怎么写

每次请求前必须调用 curl_global_init(CURL_GLOBAL_DEFAULT),且整个进程只需一次;实际请求用 curl_easy_init() 创建句柄,设置 URL 后调用 curl_easy_perform() 即可。

常见疏漏点:

  • curl_easy_setopt() 的参数顺序不能错,比如 CURLOPT_URL 必须传 const char*,传 std::String.c_str() 要确保字符串生命周期覆盖请求过程
  • 忘记检查 curl_easy_perform() 返回值,它返回 CURLE_OK 才算成功,否则是网络错误(如 CURLE_COULDNT_RESOLVE_HOST)或协议错误(如 CURLE_HTTP_RETURNED_ERROR
  • 没设超时,curl_easy_setopt(handle, CURLOPT_TIMEOUT, 10L) 建议必加,否则 DNS 卡住或服务器不响应会阻塞很久
auto handle = curl_easy_init(); if (!handle) return; curl_easy_setopt(handle, CURLOPT_URL, "https://httpbin.org/get"); curl_easy_setopt(handle, CURLOPT_TIMEOUT, 10L); CURLcode res = curl_easy_perform(handle); curl_easy_cleanup(handle);

POST 提交 json 数据的关键配置

发 JSON 不是简单把字符串塞进 CURLOPT_POSTFIELDS 就完事,HTTP 头和编码行为必须显式控制。

立即学习C++免费学习笔记(深入)”;

必须设置的项:

  • CURLOPT_POSTFIELDS 设为 JSON 字符串指针(注意不是 std::string 对象本身)
  • CURLOPT_POSTFIELDSIZE 显式传长度,避免 libcurl 错判结尾的
  • CURLOPT_HTTPHEADER"Content-Type: application/json",否则服务端可能拒收
  • 如果服务端要求认证,加 "Authorization: Bearer xxx" 到 header 列表里
std::string json = R"({"key":"value"})"; struct curl_slist* headers = nullptr; headers = curl_slist_append(headers, "Content-Type: application/json"); curl_easy_setopt(handle, CURLOPT_URL, "https://httpbin.org/post"); curl_easy_setopt(handle, CURLOPT_POSTFIELDS, json.c_str()); curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, json.size()); curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); curl_easy_perform(handle); curl_slist_free_all(headers);

如何捕获响应体和状态码

默认情况下响应内容被丢弃,得用 CURLOPT_WRITEFUNCTION + CURLOPT_WRITEDATA 自定义接收逻辑;状态码需在请求后用 curl_easy_getinfo() 获取。

典型做法:

  • 准备一个 std::string 缓冲区,传给 CURLOPT_WRITEDATA
  • 写一个静态回调函数,把收到的数据追加进缓冲区(注意:libcurl 可能多次调用该函数)
  • 请求完成后,用 curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &code) 取状态码
  • 不要依赖回调函数里拿到的状态码——它还没出来,得等 curl_easy_perform() 返回后再查
std::string response_body; auto write_callback = [](char* ptr, size_t size, size_t nmemb, void* userdata) -> size_t {     auto& buf = *static_cast(userdata);     buf.append(ptr, size * nmemb);     return size * nmemb; }; curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response_body); long http_code = 0; curl_easy_perform(handle); curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &http_code);

HTTPS 证书验证失败怎么办

开发阶段遇到 CURLE_ssl_CACERTCURLE_PEER_FaiLED_VERIFICATION 错误,本质是 libcurl 找不到可信 CA 证书路径,或目标站点证书异常。

安全做法是配对证书路径,而非关验证:

  • linux 上通常用 /etc/ssl/certs/ca-certificates.crtmacOS 用 /opt/homebrew/etc/ca-certificates/cert.pem(Homebrew 安装的 curl)
  • windows 需手动下载 Mozilla CA 包,设 CURLOPT_CAINFO 指向该文件
  • 临时调试可设 CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOST 为 0L,但上线前必须撤掉
  • 自签名内网服务,可用 CURLOPT_SSL_CTX_FUNCTION 注入自定义验证逻辑,不过极少需要

证书路径不对比网络不通更难排查——libcurl 不会告诉你“CA 文件不存在”,只报验证失败。

text=ZqhQzanResources