libcurl使用時疑難問題:
在使用libcurl時, jwisp發現, curl_easy_perform是阻塞的方式進行下載的, curl_easy_perform執行后,程序會在這里阻塞等待下載結束(成功結束或者失敗結束).此時若正常下載一段時間后,進行網絡中斷, curl_easy_perform並不會返回失敗,而是阻塞整個程序卡在這里,此時即使網絡連接重新恢復, curl_easy_perform也無法恢復繼續下載,導致整個程序出現”死機”狀態.
但是若先斷網, 然后進行curl_easy_perform的話,會直接返回失敗,不會阻塞
在網上搜索后發現, 大家在網上遇到這個問題的很多,但是解決方法很少,下面jwisp就把網上建議的可以使用的解決方法羅列:
1. 使用multi模式下載,而不使用easy模式,此方法的唯一好處就是multi並不會阻塞,而是立即返回.但是缺點是帶來了問題,其一就是需要自己去阻塞,當我們需要返回時再返回,其二還需要啟動一個線程,需要自己控制整個過程的節奏.
2. 在下載中,另起一個線程,若發現下載狀態卡死(可以通過定期檢查文件大小來實現),則從外部中斷下載線程.此方法需另起線程,而且直接中斷線程,會給整個程序帶來不穩定.
主要的設計思路如下, 下載過程中,設置超時時間為30秒, 30秒后若下載未完成就重新連接進行下載(這個可解決卡死問題)。
超時代碼設計如下:
curl_easy_setopt( curl, CURLOPT_VERBOSE, 1L ); //在屏幕打印請求連接過程和返回http數據 curl_easy_setopt( curl, CURLOPT_TIMEOUT, 10 );//接收數據時超時設置,如果10秒內數據未接收完,直接退出 curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1); // 以下3個為重定向設置 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); //返回的頭部中有Location(一般直接請求的url沒找到),則繼續請求Location對應的數據 curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 1);//查找次數,防止查找太深 curl_easy_setopt( curl, CURLOPT_CONNECTTIMEOUT, 3 );//連接超時,這個數值如果設置太短可能導致數據請求不到就斷開了