
libcurl CURLMOPT_PIPELINING 完全指南开启 HTTP/2 与 HTTP/3 多路复用传输【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl导读CURLMOPT_PIPELINING是 libcurl 多接口multi interface中用于控制连接复用行为的核心选项它决定了并行传输到同一主机的多个请求能否共享同一条 TCP 连接。本文以 docs/libcurl/opts/CURLMOPT_PIPELINING.md 为骨架结合仓库中 lib/multi.c、lib/url.c 等源码实现系统讲解该选项的位掩码语义、默认值演进历史、底层判定逻辑、配套选项以及完整的多接口使用示例。读完本文你将掌握如何在 libcurl 应用中正确开启多路复用理解它与 HTTP/1 pipelining 的差异并能结合CURLMOPT_MAX_HOST_CONNECTIONS、CURLMOPT_MAX_TOTAL_CONNECTIONS等选项精确控制连接并发策略。选项概览项目说明选项名CURLMOPT_PIPELINING所属接口multi interface多接口参数类型long位掩码 bitmask适用协议HTTPHTTP/2、HTTP/3引入版本7.16.0选项本身多路复用位 7.43.0默认值自 7.62.0 起为CURLPIPE_MULTIPLEX该选项通过curl_multi_setopt()设置声明原型位于 docs/libcurl/opts/CURLMOPT_PIPELINING.md 的 SYNOPSIS 部分#include curl/curl.h CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_PIPELINING, long bitmask);位掩码语义三个取值及其含义CURLMOPT_PIPELINING接受一个long类型的位掩码三个位的定义位于 include/curl/multi.h/* bitmask bits for CURLMOPT_PIPELINING */ #define CURLPIPE_NOTHING 0L #define CURLPIPE_HTTP1 1L #define CURLPIPE_MULTIPLEX 2LCURLPIPE_NOTHING (0)不做任何多路复用尝试传0L即CURLPIPE_NOTHING时libcurl 完全不尝试多路复用。每个新传输都倾向于建立独立连接或仅依靠普通的 keep-alive 连接复用同一时间一条连接上只跑一个传输。CURLPIPE_HTTP1 (1)已废弃无实际效果CURLPIPE_HTTP1位用于启用 HTTP/1.1 pipelining但自7.62.0起 HTTP/1 pipelining 支持已被移除该位现在完全无效。设置它不会报错但也不会产生任何行为。这反映了 HTTP/1.1 pipelining 在真实世界中的失败——队头阻塞、代理兼容性差等问题使其被 HTTP/2 多路复用取代。CURLPIPE_MULTIPLEX (2)开启 HTTP/2 / HTTP/3 多路复用这是当前唯一有实际作用的位。设置后libcurl 会尝试将新的传输复用到一条已建立的连接上——前提是该连接使用HTTP/2 或 HTTP/3HTTP/2 通过 ALPN 协商或--http2显式启用HTTP/3 需要构建时启用 QUIC 支持见 docs/HTTP3.md。在 lib/multi.c 中选项被转换为多句柄内部的布尔标志case CURLMOPT_PIPELINING: multi-multiplexing va_arg(param, long) CURLPIPE_MULTIPLEX ? 1 : 0; break;可以看到实现层面只关心CURLPIPE_MULTIPLEX这一位CURLPIPE_HTTP1位在此被直接忽略——与文档所述无效果完全一致。默认值默认开启多路复用文档明确说明自 7.62.0 起默认值为CURLPIPE_MULTIPLEX在此之前默认是CURLPIPE_NOTHING。仓库源码印证了这一默认行为。在 lib/multi.c 的curl_multi_init()初始化路径中multi-multiplexing TRUE; multi-max_concurrent_streams 100;也就是说只要创建一个 multi 句柄多路复用默认就是打开的无需显式调用curl_multi_setopt()。因此在现代 libcurl 中显式设置CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX更多是防御性编程或提升代码可读性的写法——它确保即使库的默认策略在未来变化你的应用行为依然稳定。需要注意的是多路复用可用并不等于必然发生最终是否真正复用连接还取决于目标服务器是否协商出 HTTP/2 或 HTTP/3见下文源码分析以及服务器允许的并发流上限默认max_concurrent_streams 100可通过CURLMOPT_MAX_CONCURRENT_STREAMS调整。底层实现libcurl 如何决定复用连接开关的读取入口多路复用开关通过Curl_multiplex_wanted()暴露给上层定义于 lib/multi.c/* Return TRUE if the application asked for multiplexing */ bool Curl_multiplex_wanted(const struct Curl_multi *multi) { return multi multi-multiplexing; }该函数声明于 lib/multiif.h被 url.c 等连接管理模块调用。复用判定函数 xfer_may_multiplex()真正决定这条传输能否放到那条连接上的判定逻辑位于 lib/url.cstatic bool xfer_may_multiplex(const struct Curl_easy *data, const struct connectdata *conn) { #ifndef CURL_DISABLE_HTTP /* If an HTTP protocol and multiplexing is enabled */ if((conn-scheme-protocol PROTO_FAMILY_HTTP) (!conn-bits.protoconnstart || !conn-bits.close)) { if(Curl_multiplex_wanted(data-multi) (data-state.http_neg.allowed (CURL_HTTP_V2x | CURL_HTTP_V3x))) /* allows HTTP/2 or newer */ return TRUE; } #else (void)data; (void)conn; #endif return FALSE; }从源码可以提炼出三条硬性条件缺一不可协议必须是 HTTP 家族PROTO_FAMILY_HTTPFTP、SMTP 等协议不参与多路复用协议协商已允许 HTTP/2 或 HTTP/3CURL_HTTP_V2x | CURL_HTTP_V3x这依赖 TLS 握手期间的 ALPN 扩展或 h2c 升级流程多路复用开关已打开Curl_multiplex_wanted(data-multi)即CURLMOPT_PIPELINING的CURLPIPE_MULTIPLEX位有效。注意连接本身还需满足!conn-bits.protoconnstart || !conn-bits.close连接尚未开始协议或未被标记关闭这是保证复用安全的附加约束。完整示例并行下载与多路复用文档给出的最小示例仅展示设置选项本身这里给出一个可直接运行、可观察多路复用效果的完整多接口示例。该写法与 docs/examples/crawler.c、docs/examples/http2-download.c 等仓库示例的骨架一致#include curl/curl.h #include stdio.h #define NR 4 int main(void) { CURL *easy[NR]; CURLM *m; CURLMcode res; int still_running 1; int i; curl_global_init(CURL_GLOBAL_DEFAULT); m curl_multi_init(); /* 自 7.62.0 起 CURLPIPE_MULTIPLEX 已是默认值此处显式设置以保证行为明确 */ curl_multi_setopt(m, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); for(i 0; i NR; i) { easy[i] curl_easy_init(); curl_easy_setopt(easy[i], CURLOPT_URL, https://example.com/file); curl_easy_setopt(easy[i], CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); /* 显式允许 HTTP/2 */ curl_multi_add_handle(m, easy[i]); } do { res curl_multi_perform(m, still_running); if(res ! CURLM_OK) break; if(still_running) res curl_multi_poll(m, NULL, 0, 1000, NULL); } while(still_running res CURLM_OK); /* 清理 */ for(i 0; i NR; i) curl_multi_remove_handle(m, easy[i]); curl_multi_cleanup(m); curl_global_cleanup(); return 0; }验证要点如果目标服务器支持 HTTP/2这 4 个并行传输将共享同一条 TCP 连接服务端可通过单个连接上的多个 stream 观察到如果不支持libcurl 会退化为每条连接一个传输的普通并行模式。可以用CURLOPT_VERBOSE观察日志中的连接复用与 stream 活动。更多 HTTP/2 多路复用场景可参考仓库示例 docs/examples/http2-upload.c 与 docs/examples/http2-serverpush.c。配套选项精确控制连接池与并发上限多路复用开启后连接池策略通常需要配合以下选项调优均定义于 include/curl/multi.h 附近的选项表中选项作用默认值CURLMOPT_MAX_HOST_CONNECTIONS限制同一主机上同时建立的连接数上限超出后新传输排队等待复用0无限制CURLMOPT_MAX_TOTAL_CONNECTIONS限制整个 multi 句柄的总连接数上限0无限制CURLMOPT_MAXCONNECTS连接缓存大小多路复用场景下建议增大以缓存更多空闲连接4CURLMOPT_MAX_CONCURRENT_STREAMS单条 HTTP/2/3 连接上允许的最大并发流数100CURLMOPT_PIPELINING_SITE_BL站点黑名单曾是 pipelining 时代的配套选项NULL其中CURLMOPT_PIPELINING_SITE_BL见 docs/libcurl/opts/CURLMOPT_PIPELINING_SITE_BL.md的文档明确写道No function since pipelining was removed in 7.62.0.——它和CURLMOPT_PIPELINING_SERVER_BL、CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE、CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE、CURLMOPT_MAX_PIPELINE_LENGTH一样都是 HTTP/1 pipelining 时代的遗留选项如今已无实际功能仅保留 API 兼容。仓库测试 tests/libtest/lib1550.c 仍在使用CURLMOPT_PIPELINING_SERVER_BL与CURLMOPT_PIPELINING_SITE_BL验证 API 的可用性设置后不报错但不会产生复用行为。相关选项速查See-also文档末尾列出的相关选项可作为深入阅读的索引CURLMOPT_CHUNK_LENGTH_PENALTY_SIZECURLMOPT_CONTENT_LENGTH_PENALTY_SIZECURLMOPT_MAXCONNECTSCURLMOPT_MAX_HOST_CONNECTIONSCURLMOPT_MAX_PIPELINE_LENGTHCURLMOPT_PIPELINING_SITE_BL返回值与错误处理curl_multi_setopt()返回CURLMcodeCURLM_OK (0)设置成功非零值发生错误具体错误码参见 docs/libcurl/curl_multi_setopt.md 及 libcurl-errors 文档。对CURLMOPT_PIPELINING而言任何合法的long值包括未知高位都不会导致错误——实现中仅提取CURLPIPE_MULTIPLEX位并忽略其余部分。版本演进时间线结合文档 HISTORY 与仓库现状梳理如下7.16.0CURLMOPT_PIPELINING选项引入支持 HTTP/1.1 pipelining7.30.0配套的CURLMOPT_PIPELINING_SITE_BL、CURLMOPT_PIPELINING_SERVER_BL等选项引入7.43.0新增CURLPIPE_MULTIPLEX位支持 HTTP/2 多路复用7.62.0HTTP/1 pipelining 支持被移除CURLPIPE_HTTP1位失效相关黑名单/惩罚选项一并失效CURLPIPE_MULTIPLEX成为默认值。当前仓库lib/multi.c中multi-multiplexing TRUE的默认初始化正是 7.62.0 行为演进的代码级呈现。常见误区与注意事项CURLPIPE_HTTP1已死不要为了启用 HTTP/1 pipelining而设置它该位自 7.62.0 起无任何效果pipelining 时代遗留选项同理。多路复用 ≠ 必然复用开启开关只是必要条件之一最终取决于服务器是否协商出 HTTP/2/HTTP/3可通过CURLOPT_HTTP_VERSION显式指定CURL_HTTP_VERSION_2_0以增强协商成功率。默认已开启自 7.62.0 起无需显式设置即可获得多路复用能力显式设置的价值在于明确意图与抵御未来默认策略变化。配套调整连接池在高并发多路复用场景下适当调大CURLMOPT_MAXCONNECTS并设置CURLMOPT_MAX_HOST_CONNECTIONS/CURLMOPT_MAX_TOTAL_CONNECTIONS可以避免连接数失控或排队行为不符合预期。【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考