使用libcurl實現跨平台文件傳輸


libcurl資料:

  1. 百度百科libcurl.
  2. libcurl官方文檔.

Easy  Interface:

    Easy Interface是libcurl提供的同步接口,  效率高,  容易使用, 推薦沒有特殊需求的客戶端應用均使用此類接口。

    Easy Interface主要接口

curl_easy_init() 
curl_easy_cleanup() 
curl_easy_setopt() 
curl_easy_perform() 
curl_easy_getinfo()

以上5個接口提供了libcurl同步的主要操作。

  • 使用curl_easy_init()初始化獲取一個handle。
  • 使用curl_easy_setopt()設置傳輸選項。
  • 使用curl_easy_perform()開始傳輸數據,由於是同步傳輸,因此線程會在此處堵塞。
  • 使用curl_easy_getinfo()在傳輸回調過程中或傳輸結束之后獲取相關信息。
  • 使用curl_easy_cleanup()清除handle。

使用Easy Interface實現Http GET方法的簡單示例:

 
#define CURL_BREAK_IF_NOT_OK(code)     if (code != CURLE_OK) break

size_t test_save(void *ptr, size_t size, size_t nmemb, void *stream)
{
    size_t sizes = size * nmemb;
    FILE *fp = (FILE *)(stream);
    size_t ret = 0;
    ret = fwrite(ptr,1,sizes,fp);
    assert(sizes == ret);
    return sizes;
}

int test_get(const char *url, FILE *fp)
{
    CURL *pCurl = curl_easy_init();
    int responseCode = -1;
    CURLcode returnCode = CURLE_OK;
    do 
    {
        if(!pCurl)
        {
            break;
        }
       returnCode = curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, 10); //設置連接超時時間
        CURL_BREAK_IF_NOT_OK(returnCode);

        returnCode = curl_easy_setopt(pCurl, CURLOPT_URL, url);              //設置請求鏈接
        CURL_BREAK_IF_NOT_OK(returnCode);

        returnCode = curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, fp);      //設置CURLOPT_WRITEFUNCTION的最后一個參數值
        CURL_BREAK_IF_NOT_OK(returnCode);

        returnCode = curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, test_save); //設置接收到數據之后的回調函數
        CURL_BREAK_IF_NOT_OK(returnCode);

        returnCode = curl_easy_perform(pCurl);                                    //開始傳輸
        CURL_BREAK_IF_NOT_OK(returnCode);

        returnCode = curl_easy_getinfo(pCurl, CURLINFO_RESPONSE_CODE, &responseCode); //獲取返回信息
    } while (0);
    if (pCurl) 
    {
        curl_easy_cleanup(pCurl);
    }
    return responseCode;
}

處理在傳輸中途發生網絡異常

    libcurl的Easy Interface使用同步, 無法像異步一樣隨意控制無壓力,以下2種情況均可能引發curl_easy_perform阻塞卡死。

  • 下載某些大文件時,由於本地路由器流量控制,網絡未斷開,但是卻無法接收到數據。
  • 下載過程中,網絡異常中斷。

解決方案:

  • 使用Multi接口。  Multi為異步接口, 犧牲了一部分效率確保了大部分靈活性,當然使用復雜度也相對上升。
  • 設置下載超時時間(CURLOPT_TIMEOUT)。設置超時時間后,curl會在超過此時間后無論正處於什么狀態都會跳出堵塞,此種方案適用於小文件的下載,當然你也可以在超時之后重復連接以滿足大文件的下載需求。
  • 使用回調函數返回abort value.此種方法是最簡單方便的方法。一般這樣操作, 1.設置進度回調函數,2. 在回調函數里面判斷某個時間內有沒有接收到數據,如超時返回非0值。

部分Http GET方法常用的curl_easy_setopt宏

  • CURLOPT_ERRORBUFFER 設置錯誤字符串buffer
  • CURLOPT_FAILONERROR >300的Http錯誤碼不進行回寫
  • CURLOPT_TIMEOUT 設置下載超時時間
  • CURLOPT_CONNECTTIMEOUT 設置連接超時時間
  • CURLOPT_URL 設置請求url
  • CURLOPT_HEADERFUNCTION 設置接收到Http頭回調
  • CURLOPT_HEADERDATA 設置HEADERFUNCTION回調函數的最后一個參數
  • CURLOPT_WRITEFUNCTION 設置接收到文件內容回調
  • CURLOPT_WRITEDATA 設置WRITEFUNCTION 回調函數的最后一個參數
  • CURLOPT_PORT 設置請求端口號
  • CURLOPT_NOPROGRESS 如果需要進度回調此值必須設置為0
  • CURLOPT_PROGRESSFUNCTION 設置進度回調函數
  • CURLOPT_PROGRESSDATA 設置PROGRESSFUNCTION 回調函數的最后一個參數
  • CURLOPT_RANGE 設置請求文件偏移值 例如“1000-”表示1000字節偏移開始的所有數據
  • CURLOPT_NOBODY 不接收文件content, 一般用於實現HEAD方法
  • CURLOPT_FOLLOWLOCATION 允許被抓取的鏈接跳轉(特別注意的是,如果使用CDN,此處選項必須設置為1,否則可能訪問不到真實地址)

轉載請注明地址:http://www.cnblogs.com/just-live/archive/2012/11/04/2753236.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM