You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ libcurl如何从curl multi handle中获取多请求完成后的响应数据

libcurl 多请求传输模式下获取完整响应的实现方式

libcurl 没有提供和 PHP 中 multi_get_content() 功能完全对应的直接获取响应的接口,响应内容需要你提前为每个 CURL* 类型的 easy handle 配置回调存储,传输完成后从自定义存储中读取即可,具体实现步骤如下:

实现步骤

  • 首先定义自定义响应存储结构,用于存储每个请求的响应体、HTTP 状态码等信息
struct HttpResponse {
    std::string body; // 存储完整响应体
    long http_status = 0; // 存储HTTP响应状态码
    CURLcode curl_err = CURLE_OK; // 存储libcurl执行错误码
};
  • 实现libcurl要求格式的写回调函数,libcurl收到响应数据时会自动调用该函数,把数据写入到你自定义的结构中
size_t write_data_cb(void* buffer, size_t size, size_t nmemb, void* user_ptr) {
    size_t data_len = size * nmemb;
    HttpResponse* resp = static_cast<HttpResponse*>(user_ptr);
    resp->body.append(static_cast<char*>(buffer), data_len);
    return data_len;
}
  • 初始化每个请求的easy handle时,绑定回调和对应的响应存储实例,再加入multi handle
// multi handle初始化(你应该已经完成了这一步)
CURLM* multi_handle = curl_multi_init();
// 存储easy handle和对应响应实例的映射关系,方便后续读取
std::unordered_map<CURL*, HttpResponse*> handle_map;

// 单个请求的初始化逻辑(批量创建多个easy handle时重复这段即可)
CURL* easy_handle = curl_easy_init();
HttpResponse* resp = new HttpResponse();
curl_easy_setopt(easy_handle, CURLOPT_URL, "你的请求地址");
// 绑定写回调
curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, write_data_cb);
// 把当前请求对应的响应存储实例传给回调
curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, resp);
// 加入multi队列
curl_multi_add_handle(multi_handle, easy_handle);
// 保存映射关系
handle_map[easy_handle] = resp;
  • multi传输完成后,遍历CURLMsg获取执行状态的同时,直接从映射的响应实例中取完整内容
int pending_msg_cnt;
while (CURLMsg* msg = curl_multi_info_read(multi_handle, &pending_msg_cnt)) {
    if (msg->msg == CURLMSG_DONE) {
        CURL* done_handle = msg->easy_handle;
        HttpResponse* resp = handle_map[done_handle];
        resp->curl_err = msg->data.result;
        
        if (resp->curl_err == CURLE_OK) {
            // 读取HTTP状态码
            curl_easy_getinfo(done_handle, CURLINFO_RESPONSE_CODE, &resp->http_status);
            // 此处resp->body就是当前请求的完整响应体,可以直接使用
        }
        
        // 资源清理
        curl_multi_remove_handle(multi_handle, done_handle);
        curl_easy_cleanup(done_handle);
        delete resp;
    }
}
// 所有请求处理完成后清理multi handle
curl_multi_cleanup(multi_handle);

注意事项

  • 写回调的返回值必须等于实际写入的字节数,也就是等于传入的size * nmemb,如果返回值不一致,libcurl会认为写入出错,终止当前请求。
  • 每个easy handle必须对应独立的HttpResponse实例,不要多个handle共用同一个存储地址,会导致响应数据串扰。
  • 如果需要获取响应头内容,可以额外配置CURLOPT_HEADERFUNCTION和CURLOPT_HEADERDATA,实现逻辑和获取响应体完全一致。

内容的提问来源于stack exchange,提问作者noah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 08:42:01