libcurl文件断点续传下载

    #include "stdafx.h"
    #include "curl.h"
    #include <string>
    using namespace std;
    
    size_t OnGetHeaderInfo(void *ptr, size_t size, size_t nmemb, void *stream)
    {
        long *pInfoHeader = static_cast<long*>(stream);
        if (pInfoHeader)
        {
            if (strstr((char*)ptr, "Accept-Ranges: bytes") != NULL)
                pInfoHeader[0] = 1;
    
            long len = 0;
            int ret = sscanf((char*)ptr, "Content-Length: %ld\n", &len);
            if (ret) pInfoHeader[1] = len;
        }
    
        return size * nmemb;
    }
    
    int DownloadFile(const char* pszUrl, const char* pszFile)
    {
        CURLcode ret = CURLE_OK;
        long infoHeader[2] = {0, 0}; // [0] = accept ranges or not, [1] = file size
        CURL* pCurl = NULL;
    
        // get content length
        pCurl = curl_easy_init();
        if(NULL == pCurl) return CURLE_FAILED_INIT;
    
        curl_easy_setopt(pCurl, CURLOPT_URL, pszUrl);  
        curl_easy_setopt(pCurl, CURLOPT_USERAGENT, "SobetClient");
        curl_easy_setopt(pCurl, CURLOPT_HEADER, 1);
        curl_easy_setopt(pCurl, CURLOPT_NOBODY, 1);
        curl_easy_setopt(pCurl, CURLOPT_HEADERFUNCTION, OnGetHeaderInfo);
        curl_easy_setopt(pCurl, CURLOPT_HEADERDATA, &infoHeader);
        curl_easy_perform(pCurl);
        curl_easy_cleanup(pCurl);
    
        // download file from last broken point if server support range
        pCurl = curl_easy_init();
        if(NULL == pCurl) return CURLE_FAILED_INIT;  
    
        FILE* pFile = NULL;    
        if (infoHeader[0]) pFile = fopen( pszFile, "ab+" );
        else pFile = fopen( pszFile, "wb+" );
        if (pFile == NULL)
        {
            curl_easy_cleanup(pCurl);
            return -1;
        }
    
        curl_easy_setopt(pCurl, CURLOPT_URL, pszUrl);  
        curl_easy_setopt(pCurl, CURLOPT_USERAGENT, "SobetClient");
        curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, pFile);  
        curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, NULL);  
        curl_easy_setopt(pCurl, CURLOPT_FOLLOWLOCATION, 1);
        curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1);
    
        int nTryCount = 3;
        for (int i = 0; i < nTryCount; i++)
        {
            if (infoHeader[0])
            {
                fseek(pFile, 0, SEEK_END);
                int nSize = ftell(pFile);
                if (nSize >= infoHeader[1] && infoHeader[1] > 0) break; //already finished download
                char szRange[32] = {0}; sprintf_s(szRange, 31, "%d-", nSize);
                curl_easy_setopt(pCurl, CURLOPT_RANGE, szRange);
            }
    
            ret = curl_easy_perform(pCurl);  
            if (ret != CURLE_OK) continue;
    
            int nHttpCode = 0;
            ret = curl_easy_getinfo(pCurl, CURLINFO_RESPONSE_CODE, &nHttpCode); 
            if (ret != CURLE_OK) continue;
            if ( !(nHttpCode >= 200 && nHttpCode < 300) ) ret = CURLE_REMOTE_FILE_NOT_FOUND;
            break;
        }
    
        curl_easy_cleanup(pCurl);
        fclose(pFile);
        //if (ret != CURLE_OK) DeleteFile(pszFile);
    
        return ret;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        int ret = 0;
        ret = DownloadFile("http://skycnxz1.wy119.com/cloudmusicsetup_1_9_2.109452.exe", "c:\\cloudmusicsetup_1_9_2.109452.exe");
        printf("ret: %d", ret);
    
        return 0;
    }
    


    本站所有文章如无特别注明均为原创。
    转载请注明:流倏 » libcurl文件断点续传下载

    点赞 | 0

已经有3 人抢在你前面了~

  • dolpstar 2年前 (2016-12-26)

    卢比666

    • Julissa 1年前 (2017-01-06)

      It’s much easier to unadnsterd when you put it that way!

  • Darence 1年前 (2017-01-06)

    Thanks for coguiibttrnn. It’s helped me understand the issues.