最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
C++中libcurl中curl_easy_perform卡死问题
时间:2022-06-25 08:01:29 编辑:袖梨 来源:一聚教程网
Libcurl为一个免费开源的,客户端url传输库,本文主要分析使用过程中遇到的卡死问题。
问题描述
LibCurl使用阻塞的方式来进行http下载,curl_easy_perform执行后,程序会在这里阻塞等待下载结束(成功OR失败),此时若下载一段时间后出现网络异常,curl_easy_perform不会返回失败,整个线程阻塞卡死。
问题分析
复现:连接无线网络,然后执行curl_easy_perform下载,下载过程中,断开无线网络,curl_easy_perform卡死,阻塞整个线程。
原因:当断开无线网络时,使用命令行netstat ano | findstr ‘连接ip’, 可以发现LibCurl的http连接并没有断开(不知道是不是windows系统的bug),如果将CURLOPT_TIMEOUT设置为无限等待,curl_easy_perform便会一直阻塞住线程。
解决方案
1、如果我们不将CURLOPT_TIMEOUT设置为无限等待,是不会出现上面问题,curl_easy_perform会在执行一段时间(由CURLOPT_TIMEOUR设置),结束并返回失败,但是如果设置合适的CURLOPT_TIMEOUT是个问题。
1
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 0); // blocking forever, cannot find a suitable value
2、使用multi模式下载, 而不使用easy模式, 此方法的唯一好处就是multi并不会阻塞, 而是立即返回. 但是缺点是带来了问题, 其一就是需要自己去阻塞, 当我们需要返回时再返回, 其二还需要启动一个线程, 需要自己控制整个过程的节奏。
3、在下载中, 另起一个线程, 若发现下载状态卡死(可以通过定期检查文件大小来实现), 则从外部中断下载线程. 此方法需另起线程, 而且直接中断线程, 会给整个程序带来不稳定。
4、设置CURLOPT_TIMEOUT为30s,以30s为间隔断点续传。
5、使用CURLOPT_LOW_SPEED_LIMIT, CURLOPT_LOW_SPEED_TIME
res = curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1024L);
res = curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 30L);
6、使用CURLOPT_PROGRESSFUNCTION设置进度表回调函数,可以在该回调函数内部检测下载是否出错,如果出现就中断curl_easy_perform,返回下载错误。
#include
int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROGRESSFUNCTION, progress_callback);
相关文章
- 王者荣耀侦探能力大测试攻略 王者荣耀侦探能力大测试怎么过 11-22
- 无期迷途主线前瞻兑换码是什么 11-22
- 原神欧洛伦怎么培养 11-22
- 炉石传说网易云音乐联动怎么玩 11-22
- 永劫无间手游确幸转盘怎么样 11-22
- 无期迷途主线前瞻兑换码是什么 无期迷途主线前瞻直播兑换码介绍 11-22