特点
libcurl基本是线程安全的,但在多线程环境下需要注意- 避免在多个线程中共享同一个
CURL句柄- 使用共享句柄(
CURLSH)时需特别注意线程安全
- 使用共享句柄(
性能
-
考虑使用持久连接(
Keep-Alive)- 尽可能重用
CURL句柄以利用持久连接(Keep-Alive),这可以提高性能
- 尽可能重用
-
根据需要设置合适的超时选项
安全
- 如果涉及敏感数据,确保使用
HTTPS - 考虑验证服务器的
SSL证书
断点续传
- 如果需要,可以通过设置
CURLOPT_RANGE来支持断点续传
基本步骤
- 初始化
- 初始化
libcurl库
- 初始化
|
1 |
curl_global_init(CURL_GLOBAL_ALL); |
- 创建
curl句柄
|
1 |
CURL* pCurl = curl_easy_init(); |
- 设置
curl选项
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// 目标文件的url curl_easy_setopt(curl, CURLOPT_URL, path.c_str()); // 告诉 libcurl 执行一个 "HEAD" 请求而不是 "GET" 请求 // 意味着 libcurl 将不会下载页面内容,只会获取 HTTP 头信息 // 这在只需要知道资源的信息(如类型或大小)而不需要实际内容时非常有用 curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); // 用于控制 libcurl 是否验证 SSL 证书的有效性 // 将其设置为 0L (即 false) 会使 libcurl 不验证 SSL 证书的合法性 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // 决定 libcurl 是否验证服务器证书中的主机名是否匹配请求的主机名 // 设置为 0L 表示不进行检查 url_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); // 用于控制 libcurl 在与服务器通信时是否使用 SSL/TLS // CURLUSESSL_NONE 指定不使用 SSL/TLS // 这个设置在不需要加密通信时有用,但如果是处理敏感信息,建议启用 SSL url_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_NONE); |
- 执行
curl请求- 需要检查返回值,以确定是否发生了错误
- 使用
curl_easy_strerror()函数获取错误描述
|
1 2 |
CURLcode res; res = curl_easy_perform(curl); |
- 资源清理
- 使用
curl_easy_cleanup()清理CURL句柄 - 使用
curl_global_cleanup()清理libcurl库(通常在程序结束时执行)
- 使用
其他选项
URL
CURLOPT_URL:设置请求的URLCURLOPT_REFERER:设置HTTP Referer头部
网络选项
CURLOPT_TIMEOUT:设置最大请求时间CURLOPT_CONNECTTIMEOUT:设置连接超时时间CURLOPT_FOLLOWLOCATION:启用或禁用重定向
SSL/TLS
CURLOPT_SSL_VERIFYPEER:是否验证对等证书CURLOPT_SSL_VERIFYHOST:验证服务器证书的主机名CURLOPT_CAINFO:指定一个包含受信任CA证书的文件
HTTP
CURLOPT_USERAGENT:设置用户代理CURLOPT_HTTPHEADER:设置自定义HTTP头部CURLOPT_COOKIE:设置发送到服务器的CookieCURLOPT_POST:启用或禁用POST请求CURLOPT_POSTFIELDS:设置POST请求的数据
数据处理
CURLOPT_WRITEFUNCTION:指定写入数据的回调函数CURLOPT_READFUNCTION:指定读取数据的回调函数CURLOPT_WRITEDATA:设置写入数据的指针(通常是文件指针或内存缓冲区)CURLOPT_HEADERFUNCTION:指定处理头部数据的回调函数
认知和安全
CURLOPT_USERNAME和CURLOPT_PASSWORD:设置用于服务器认证的用户名和密码CURLOPT_HTTPAUTH:设置HTTP认证方法(如基本、摘要等)
性能和行为
CURLOPT_VERBOSE:启用详细模式,用于调试CURLOPT_NOPROGRESS:启用或禁用进度回调函数CURLOPT_NOSIGNAL:指示 libcurl 是否应使用信号
上传和下载
CURLOPT_UPLOAD:启用或禁用上传模式CURLOPT_INFILESIZE:设置要上传的文件的大小
QA
每一个curl句柄对应着一个持久连接吗
- 每个
CURL句柄并不自动对应一个持久连接(Keep-Alive) - 但
libcurl支持在多个请求之间重用连接,这是通过HTTP的Keep-Alive特性实现的
http keep-alive libcurl
HTTP/1.1协议默认开启了Keep-Alive特性,它允许在同一TCP连接上发送和接收多个HTTP请求/响应,而不是每个请求/响应都建立新的连接- 这种机制减少了连接和断开的开销,提高了效率,特别是在多个请求发送到同一服务器时
- 当使用
libcurl发送请求时,如果服务器支持Keep-Alive,libcurl会尝试复用现有的TCP连接,而不是每次请求都建立新连接 - 为了重用连接,你需要使用同一个
CURL句柄进行多次请求,或者使用libcurl的多接口来管理多个句柄- 对同一个服务器进行多个请求时,可以用同一个
CURL句柄重复调用curl_easy_perform()
这样做时,libcurl会尝试重用该句柄的连接 - 对于并行的多个请求,可以使用
libcurl的多接口(CURLM)
多接口允许你同时处理多个CURL句柄,这些句柄在可能的情况下会共享连接
- 对同一个服务器进行多个请求时,可以用同一个
- 注意点:
- 连接重用取决于服务器是否支持
Keep-Alive - 如果服务器在响应中明确关闭了
Keep-Alive(例如通过Connection: close头部),libcurl将不会重用连接 - 即使
Keep-Alive被启用,连接也不会无限期保持开放。服务器可能会在一定时间后关闭长时间闲置的连接 DNS解析结果和SSL/TLS会话也可能被缓存并重用,这进一步提高了性能libcurl的不同版本可能在连接重用机制上有所差异,始终建议使用最新版libcurl
- 连接重用取决于服务器是否支持
libcurl连接前后
- 当初始化一个
CURL句柄时,其实是在为一个潜在的网络请求配置和准备环境,但此时还没有建立与服务器的实际连接 - 在
libcurl中,连接的建立通常发生在调用curl_easy_perform()或类似函数时,而不是在句柄初始化时- 只有在调用
curl_easy_perform()时,libcurl才真正尝试与服务器建立连接 - 当调用
curl_easy_perform()时,libcurl根据之前设置的选项建立网络连接,并执行请求 - 如果连接成功,
libcurl会发送请求(如HTTPGET或POST请求),并接收响应 - 在数据传输完成后,连接可能会根据
HTTP Keep-Alive头保持开放状态,以供后续请求重用
- 只有在调用
libcurl整体连接理解
- 建立连接
- 当调用
curl_easy_perform()时,libcurl会根据之前设置的选项尝试与服务器建立连接
- 当调用
- 底层
socket- 在建立连接的过程中,
libcurl(在底层)会为客户端创建一个socket,并通过这个socket与服务器的相应socket建立通信
- 在建立连接的过程中,
keep-alive- 如果服务器支持
Keep-Alive(HTTP/1.1默认支持),则在一次请求完成后,服务器端的socket可能不会立即关闭,而是保持一段时间的开放状态 - 在这段时间内,如果使用同一
CURL句柄发起另一个请求到相同的服务器,libcurl会尝试重用现有的socket,而不是创建一个新的
- 如果服务器支持
- 持续通信
- 当使用
Keep-Alive特性时,客户端(即libcurl)管理的socket可以在一段时间内重用,用于与服务器的持续通信
- 当使用
- 补充
- 值得注意的是,连接重用不仅限于使用相同的
CURL句柄
如果您使用libcurl的多句柄接口(CURLM),在某些情况下,libcurl可以在不同的CURL句柄之间智能地重用连接 - 服务器可能会根据其配置和负载情况决定保持连接开放的时间
也就是说,即使客户端希望重用连接,服务器也可能因为各种原因(如超时或资源限制)而关闭连接
- 值得注意的是,连接重用不仅限于使用相同的
声明:本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ COM组件_403/07
- ♥ Chromium:学习,框架,一09/02
- ♥ HTTP协议相关学习一03/22
- ♥ HTTP 协议10/22
- ♥ C++_运算符优先级&&相关性12/15
- ♥ 寄存器和内存访问03/28
热评文章
- * 暂无