如何重用 curl_easy 的连接?
How do I reuse connections with curl_easy?
我正在使用 libccurl_easy
接口编写代码url,但遇到困难
让它重用连接。详情如下。
curl --version
curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.1.1 zlib/1.2.11
libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3
Release-Date: 2018-01-24
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3
pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB
SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL
我的代码运行了一系列单元测试,所有这些都必须连接到
H2 上的同一主机,因此我设置了持久连接。我打电话
curl_easy_init 一次,然后是所有全局 curl_easy_setopt
值,然后在一个
循环,我通过调用 curl_easy_setopt
来设置 post 字段来发出请求,
url,内容长度,然后是curl_easy_perform
。
我只在所有请求都发出后才调用 curl_easy_cleanup
。
我设置了以下选项:
CURLOPT_FOLLOWLOCATION => 1
CURLOPT_SSL_VERIFYPEER => 1
CURLOPT_SSL_VERIFYHOST => 2
CURLOPT_SSLVERSION 7<<16
CURLOPT_HTTP_VERSION = 4
CURLOPT_TCP_FASTOPEN = 1
CURLOPT_TCP_KEEPALIVE = 1
CURLOPT_ACCEPT_ENCODING = ""
CURLOPT_TRANSFER_ENCODING = 1
CURLOPT_POST = 1
CURLOPT_DNS_CACHE_TIMEOUT = 0
CURLOPT_VERBOSE = 1
CURLOPT_SSLCERT
CURLOPT_SSLKEY
CURLOPT_CAINFO
详细输出如下所示:
* TCP_NODELAY set
* TCP_FASTOPEN_CONNECT set
* Connected to XYZ () port 443 (#0)
* found 3 certificates in /data/certs/ca_chain.pem
* found 401 certificates in /etc/ssl/certs
* ALPN, offering h2
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification OK
* server certificate status verification SKIPPED
* error fetching CN from cert:The requested data were not available.
* common name: (matched)
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject:
* start date: Mon, 13 Jul 2020 08:04:30 GMT
* expire date: Mon, 20 Jul 2020 08:05:00 GMT
* issuer: C=US,ST=MA,L=Cambridge,O=XXXXX,CN=YYYYY
* compression: NULL
* ALPN, server accepted to use h2
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade:
len=0
* Using Stream ID: 1 (easy handle 0x9036570)
> POST /foo/ HTTP/2
<Request>
* We are completely uploaded and fine
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
<Response>
* Connection #0 to host XYZ left intact
* Found bundle for host XYZ: 0xe141520 [can multiplex]
* Connection #0 is still name resolving, can't reuse
* Trying IP...
* TCP_NODELAY set
* TCP_FASTOPEN_CONNECT set
* Connected to XYZ () port 443 (#1)
* found 3 certificates in /data/certs/ca_chain.pem
* found 401 certificates in /etc/ssl/certs
* ALPN, offering h2
* ALPN, offering http/1.1
* SSL re-using session ID
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification OK
* server certificate status verification SKIPPED
* error fetching CN from cert:The requested data were not available.
* common name: (matched)
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject:
* start date: Mon, 13 Jul 2020 08:04:30 GMT
* expire date: Mon, 20 Jul 2020 08:05:00 GMT
* issuer: C=US,ST=MA,L=Cambridge,O=XXXXX,CN=YYYYY
* compression: NULL
* ALPN, server accepted to use h2
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade:
len=0
* Using Stream ID: 1 (easy handle 0x9036570)
<Request>
* We are completely uploaded and fine
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200
< vary: accept-encoding
< content-encoding: gzip
< content-type: text/plain
< date: Mon, 13 Jul 2020 19:30:36 GMT
< server: abcdefg
<Response>
* Connection #1 to host XYZ left intact
* Found bundle for host XYZ: 0xe141520 [can multiplex]
* Connection #0 is still name resolving, can't reuse
* Connection #1 is still name resolving, can't reuse
等等...
很快就到了:
* Connection cache is full, closing the oldest one.
* Closing connection 0
* Connection #5 to host XYZ left intact
最旧连接的关闭从这里一直持续到
要么一切都完成,要么 TLS 握手错误将连接置于
进入不一致状态。
知道如何让 curl 重用与主机的 H2 连接吗?
感谢您的宝贵时间。
问题出在 CURLOPT_TCP_FASTOPEN
。关闭该选项将允许重新使用连接。 FAST_OPEN 只有在使用多个 TCP 连接以避免握手期间的往返时才需要。
传统的 TCP 握手是一种三向协议。
- 发起方向对端发送SYN包,
- 对端用SYN-ACK数据包响应给发起者,
- 最后发起者发送自己的ACK。
发送ACK后,发起方发送第一个数据包。总共发送4个数据包。
使用 FAST_OPEN,数据传输(在第一个连接之后的连接上)可以从第一个数据包开始。它使用 TCP Cookie (TFO) 来确定两台主机最近已成功相互连接。
有关详细信息,请参阅 https://en.wikipedia.org/wiki/TCP_Fast_Open。
我正在使用 libccurl_easy
接口编写代码url,但遇到困难
让它重用连接。详情如下。
curl --version
curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.1.1 zlib/1.2.11
libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3
Release-Date: 2018-01-24
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3
pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB
SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL
我的代码运行了一系列单元测试,所有这些都必须连接到
H2 上的同一主机,因此我设置了持久连接。我打电话
curl_easy_init 一次,然后是所有全局 curl_easy_setopt
值,然后在一个
循环,我通过调用 curl_easy_setopt
来设置 post 字段来发出请求,
url,内容长度,然后是curl_easy_perform
。
我只在所有请求都发出后才调用 curl_easy_cleanup
。
我设置了以下选项:
CURLOPT_FOLLOWLOCATION => 1
CURLOPT_SSL_VERIFYPEER => 1
CURLOPT_SSL_VERIFYHOST => 2
CURLOPT_SSLVERSION 7<<16
CURLOPT_HTTP_VERSION = 4
CURLOPT_TCP_FASTOPEN = 1
CURLOPT_TCP_KEEPALIVE = 1
CURLOPT_ACCEPT_ENCODING = ""
CURLOPT_TRANSFER_ENCODING = 1
CURLOPT_POST = 1
CURLOPT_DNS_CACHE_TIMEOUT = 0
CURLOPT_VERBOSE = 1
CURLOPT_SSLCERT
CURLOPT_SSLKEY
CURLOPT_CAINFO
详细输出如下所示:
* TCP_NODELAY set
* TCP_FASTOPEN_CONNECT set
* Connected to XYZ () port 443 (#0)
* found 3 certificates in /data/certs/ca_chain.pem
* found 401 certificates in /etc/ssl/certs
* ALPN, offering h2
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification OK
* server certificate status verification SKIPPED
* error fetching CN from cert:The requested data were not available.
* common name: (matched)
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject:
* start date: Mon, 13 Jul 2020 08:04:30 GMT
* expire date: Mon, 20 Jul 2020 08:05:00 GMT
* issuer: C=US,ST=MA,L=Cambridge,O=XXXXX,CN=YYYYY
* compression: NULL
* ALPN, server accepted to use h2
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade:
len=0
* Using Stream ID: 1 (easy handle 0x9036570)
> POST /foo/ HTTP/2
<Request>
* We are completely uploaded and fine
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
<Response>
* Connection #0 to host XYZ left intact
* Found bundle for host XYZ: 0xe141520 [can multiplex]
* Connection #0 is still name resolving, can't reuse
* Trying IP...
* TCP_NODELAY set
* TCP_FASTOPEN_CONNECT set
* Connected to XYZ () port 443 (#1)
* found 3 certificates in /data/certs/ca_chain.pem
* found 401 certificates in /etc/ssl/certs
* ALPN, offering h2
* ALPN, offering http/1.1
* SSL re-using session ID
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification OK
* server certificate status verification SKIPPED
* error fetching CN from cert:The requested data were not available.
* common name: (matched)
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject:
* start date: Mon, 13 Jul 2020 08:04:30 GMT
* expire date: Mon, 20 Jul 2020 08:05:00 GMT
* issuer: C=US,ST=MA,L=Cambridge,O=XXXXX,CN=YYYYY
* compression: NULL
* ALPN, server accepted to use h2
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade:
len=0
* Using Stream ID: 1 (easy handle 0x9036570)
<Request>
* We are completely uploaded and fine
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200
< vary: accept-encoding
< content-encoding: gzip
< content-type: text/plain
< date: Mon, 13 Jul 2020 19:30:36 GMT
< server: abcdefg
<Response>
* Connection #1 to host XYZ left intact
* Found bundle for host XYZ: 0xe141520 [can multiplex]
* Connection #0 is still name resolving, can't reuse
* Connection #1 is still name resolving, can't reuse
等等...
很快就到了:
* Connection cache is full, closing the oldest one.
* Closing connection 0
* Connection #5 to host XYZ left intact
最旧连接的关闭从这里一直持续到 要么一切都完成,要么 TLS 握手错误将连接置于 进入不一致状态。
知道如何让 curl 重用与主机的 H2 连接吗?
感谢您的宝贵时间。
问题出在 CURLOPT_TCP_FASTOPEN
。关闭该选项将允许重新使用连接。 FAST_OPEN 只有在使用多个 TCP 连接以避免握手期间的往返时才需要。
传统的 TCP 握手是一种三向协议。
- 发起方向对端发送SYN包,
- 对端用SYN-ACK数据包响应给发起者,
- 最后发起者发送自己的ACK。
发送ACK后,发起方发送第一个数据包。总共发送4个数据包。
使用 FAST_OPEN,数据传输(在第一个连接之后的连接上)可以从第一个数据包开始。它使用 TCP Cookie (TFO) 来确定两台主机最近已成功相互连接。
有关详细信息,请参阅 https://en.wikipedia.org/wiki/TCP_Fast_Open。