使用libcurl下載文件小例


libcurl是一個很強大的開源網絡處理庫,支持包括HTTP、HTTPS、FTP……一系列網絡協議。用它來進行HTTP的get\post 或者下載文件更是小菜一碟,chrome內核都用到了它,本文主要講解一個使用curl下載文件的小例。

首先是去下載curl的最新源代碼,然后編譯成動態庫或者靜態庫;然后把頭文件和庫文件拿出來加入到我們自己的工程中,引用聲明:

#include "curl.h"  
#ifdef _DEBUG  
#pragma comment(lib, "../Debug/libcurld")  
#else  
#pragma comment(lib, "../Release/libcurl")  
#endif  

特意在原有代碼上加了一些注釋,希望可以更好理解,上代碼:

<pre name="code" class="cpp">// UseLibCurl.cpp : 定義控制台應用程序的入口點。  
//  
  
#include "stdafx.h"  
#include <Windows.h>  
#include <CommCtrl.h>  
#include "resource.h"  
#include "curl.h"  
#ifdef _DEBUG  
#pragma comment(lib, "../Debug/libcurld")  
#else  
#pragma comment(lib, "../Release/libcurl")  
#endif  
  
  
//這個用來保存對話框的窗口句柄,因為后面要向這個窗口發消息,必須知道其窗口句柄  
HWND    g_hDlgWnd = NULL;  
//提供給CURL下載進度回調的函數,用於保存下載的數據到文件  
static size_t   DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam);  
//提供給CURL下載進度回調的函數,用於計算下載進度通知界面  
static int ProgressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);  
//這是對話框的消息循環,在控制台程序里面創建GUI,僅僅是為了更好地展現下載回調這個功能  
INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);  
//這個是下載的線程函數,為了不把對話框主界面卡死,肯定是要自己開線程來下載的了  
DWORD WINAPI DownloadThread(LPVOID lpParam);  
  
int _tmain(int argc, _TCHAR* argv[])  
{  
    //彈出對話框,知道對話框關閉才會執行退出  
    DialogBox(NULL, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc );  
    return 0;  
}  
  
static size_t DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam)  
{  
    //把下載到的數據以追加的方式寫入文件(一定要有a,否則前面寫入的內容就會被覆蓋了)  
    FILE* fp = NULL;  
    fopen_s(&fp, "c:\\test.apk", "ab+");  
    size_t nWrite = fwrite(pBuffer, nSize, nMemByte, fp);  
    fclose(fp);  
    return nWrite;  
}  
  
static int ProgressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)  
{  
    if ( dltotal > -0.1 && dltotal < 0.1 )  
        return 0;  
    int nPos = (int) ( (dlnow/dltotal)*100 );  
    //通知進度條更新下載進度  
    ::PostMessage(g_hDlgWnd, WM_USER + 110, nPos, 0);  
    //::Sleep(10);  
    return 0;  
}  
  
INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
    switch( uMsg )  
    {  
    case WM_INITDIALOG:  
        {  
            g_hDlgWnd = hWnd;  
            HWND hProgress = GetDlgItem(hWnd, IDC_PROGRESS1);  
            SendMessage(hProgress, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) 100);  
            //對話框初始化時創建下載線程  
            HANDLE hThread = CreateThread(NULL, 0, DownloadThread, 0, 0, NULL);  
            CloseHandle(hThread);  
            ::SetWindowText(hWnd, L"使用CURL下載文件示例:");  
            return TRUE;  
        }  
    case WM_COMMAND:  
        {  
            WORD  msg = HIWORD(wParam);  
            WORD  id  = LOWORD(wParam);  
            if ( id == IDOK || id == IDCANCEL )  
                EndDialog(hWnd, id);  
            break;  
        }  
    case WM_ERASEBKGND:  
        return TRUE;  
    case WM_CTLCOLORSTATIC:  
        return (INT_PTR)(HBRUSH)::GetStockObject(WHITE_BRUSH);  
    case WM_USER + 110:  
        {//接收到設置進度的消息  
            HWND    hProgress   = GetDlgItem(hWnd, IDC_PROGRESS1);  
            HWND    hStatus     = GetDlgItem(hWnd, IDC_STATUS);  
            if ( hProgress )  
                SendMessage(hProgress, PBM_SETPOS, wParam, 0L);  
            if ( hStatus )  
            {  
                WCHAR szBuffer[100] = {0};  
                if ( wParam<100 )  
                    swprintf(szBuffer, L"正在下載文件,進度:%d%%", wParam);  
                else  
                    swprintf(szBuffer, L"文件下載完畢!");  
                ::SetWindowText(hStatus, szBuffer);  
            }  
            return 0;  
        }  
    default:  
        break;  
    }  
    return DefWindowProc(hWnd, uMsg, wParam, lParam);  
}  
  
DWORD WINAPI DownloadThread(LPVOID lpParam)  
{  
    //初始化curl,這個是必須的  
    CURL* curl = curl_easy_init();  
    curl_easy_setopt(curl, CURLOPT_URL, "http://android.shoujids.com/software/download?id=154103");  
    //設置接收數據的回調  
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DownloadCallback);  
    //curl_easy_setopt(curl, CURLOPT_INFILESIZE, lFileSize);  
    //curl_easy_setopt(curl, CURLOPT_HEADER, 1);  
    //curl_easy_setopt(curl, CURLOPT_NOBODY, 1);  
    //curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);  
    // 設置重定向的最大次數  
    curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5);  
    // 設置301、302跳轉跟隨location  
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);  
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);  
    //設置進度回調函數  
    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, ProgressCallback);  
    //curl_easy_getinfo(curl,  CURLINFO_CONTENT_LENGTH_DOWNLOAD, &lFileSize);  
    //curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, g_hDlgWnd);  
    //開始執行請求  
    CURLcode retcCode = curl_easy_perform(curl);  
    //查看是否有出錯信息  
    const char* pError = curl_easy_strerror(retcCode);  
    //清理curl,和前面的初始化匹配  
    curl_easy_cleanup(curl);  
    return 0;  
}  

原文鏈接:使用libcurl下載文件小例


免責聲明!

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



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