C++中libcurl中curl_easy_perform卡死問題

來源:互聯網
上載者:User


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 <curl/curl.h>
int progress_callback(void *clientp,   double dltotal,   double dlnow,   double ultotal,   double ulnow);
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROGRESSFUNCTION, progress_callback);

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.