天天看點

使用libcurl實作的下載下傳器

頭檔案:

使用libcurl實作的下載下傳器

/**********************************************************************

使用libcurl實作的下載下傳器

* Copyright (C) 2014 -  - All Rights Reserved

使用libcurl實作的下載下傳器

*

使用libcurl實作的下載下傳器

* 檔案名稱:        Downloader_LibCurl.h

使用libcurl實作的下載下傳器

* 摘    要:        下載下傳器 - LibCurl實作

使用libcurl實作的下載下傳器

*     

使用libcurl實作的下載下傳器

* 作    者:        yanglinbo,

使用libcurl實作的下載下傳器

* 修    改:        檢視檔案最下方.

使用libcurl實作的下載下傳器

使用libcurl實作的下載下傳器

***********************************************************************/

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

#ifndef __Downloader_LibCurl_H__

使用libcurl實作的下載下傳器

#define __Downloader_LibCurl_H__

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

#include <curl/curl.h>

使用libcurl實作的下載下傳器

#include <fstream>

使用libcurl實作的下載下傳器

#include <string>

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

class CDownloader

使用libcurl實作的下載下傳器

{

使用libcurl實作的下載下傳器

public:

使用libcurl實作的下載下傳器

    CDownloader(void);

使用libcurl實作的下載下傳器

    virtual ~CDownloader(void);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    /// 線程入口函數

使用libcurl實作的下載下傳器

    virtual bool run();

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    /// 啟動下載下傳

使用libcurl實作的下載下傳器

    virtual bool start(const std::string& strUrl, const std::string& strLocalFile);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    /// 停止下載下傳

使用libcurl實作的下載下傳器

    virtual bool stop();

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    /// 是否運作狀态

使用libcurl實作的下載下傳器

    bool isRunning() const;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

protected:

使用libcurl實作的下載下傳器

    /// 寫入回調

使用libcurl實作的下載下傳器

    static size_t handleWrite(void *buffer, size_t size, size_t nmemb, void *userp);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    /// 進度回調

使用libcurl實作的下載下傳器

    static size_t handleProgress(void *buffer, double dltotal, double dlnow, double ultotal, double ulnow);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    size_t onWrite(void *buffer, size_t size, size_t nmemb);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    size_t onProgress(const double& dltotal, const double& dlnow);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    /// 下載下傳回調

使用libcurl實作的下載下傳器

    void onDownload();

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    /// 設定libcurl選項

使用libcurl實作的下載下傳器

    void setOption();

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    /// 清除資料

使用libcurl實作的下載下傳器

    void clear();

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    CURL*            m_pCurl;                ///< libcurl句柄

使用libcurl實作的下載下傳器

    FILE*            m_pFile;                ///< 檔案指針

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    bool            m_bRunning;                ///< 運作标志

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    std::string        m_strDownloadUrl;        ///< 下載下傳連結

使用libcurl實作的下載下傳器

    std::string        m_strLocalFilePath;        ///< 本地檔案路徑

使用libcurl實作的下載下傳器

};

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

#endif

使用libcurl實作的下載下傳器

實作檔案:

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

* 檔案名稱:        Downloader_LibCurl.cpp

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

#include "StdAfx.h"

使用libcurl實作的下載下傳器

#include "Downloader.h"

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

CDownloader::CDownloader(void)

使用libcurl實作的下載下傳器

: m_pCurl(NULL)

使用libcurl實作的下載下傳器

, m_pFile(NULL)

使用libcurl實作的下載下傳器

, m_bRunning(false)

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

}

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

CDownloader::~CDownloader(void)

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    stop();

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

bool CDownloader::run()

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    onDownload();

使用libcurl實作的下載下傳器

    return true;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

bool CDownloader::isRunning() const

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    return m_bRunning;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

void CDownloader::clear()

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    if (m_pFile)

使用libcurl實作的下載下傳器

    {

使用libcurl實作的下載下傳器

        fclose(m_pFile);

使用libcurl實作的下載下傳器

        m_pFile = NULL;

使用libcurl實作的下載下傳器

    }

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    if (m_pCurl)

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

        curl_easy_cleanup(m_pCurl);

使用libcurl實作的下載下傳器

        m_pCurl = NULL;

使用libcurl實作的下載下傳器

        curl_global_cleanup();

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    m_strDownloadUrl.clear();

使用libcurl實作的下載下傳器

    m_strLocalFilePath.clear();

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

void CDownloader::setOption()

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 遠端URL,支援 http, https, ftp

使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_URL, m_strDownloadUrl.c_str());

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 設定User-Agent

使用libcurl實作的下載下傳器

    std::string useragent = _T("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1");

使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_USERAGENT, useragent.c_str());

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 設定重定向的最大次數

使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_MAXREDIRS, 5);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 設定301、302跳轉跟随location

使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);

使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_POST, false);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 下載下傳内容回調函數

使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, handleWrite);

使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, this);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 進度回調函數

使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_NOPROGRESS, 0);

使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSDATA, this);

使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSFUNCTION, handleProgress);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 跳過伺服器SSL驗證,不使用CA憑證

使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 0L);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 驗證伺服器端發送的證書,預設是 2(高),1(中),0(禁用)

使用libcurl實作的下載下傳器

    curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, 0L);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

bool CDownloader::start(const std::string& strUrl, const std::string& strLocalFile)

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    if (strUrl.empty()) return false;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    if (m_bRunning == true) return true;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    clear();

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    m_strDownloadUrl    = strUrl;

使用libcurl實作的下載下傳器

    m_strLocalFilePath    = strLocalFile;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 初始化libcurl

使用libcurl實作的下載下傳器

    m_pCurl = curl_easy_init();

使用libcurl實作的下載下傳器

    if (m_pCurl == NULL)

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

        return false;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 設定libcurl的選項

使用libcurl實作的下載下傳器

    setOption();

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 建立檔案

使用libcurl實作的下載下傳器

    m_pFile = fopen(m_strLocalFilePath.c_str(), "wb");

使用libcurl實作的下載下傳器

    if (m_pFile == NULL)

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    m_bRunning = true;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

bool CDownloader::stop()

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    m_bRunning = false;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

size_t CDownloader::handleWrite( void *buffer, size_t size, size_t nmemb, void *userp )

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    CDownloader* pDownloader = (CDownloader*) userp;

使用libcurl實作的下載下傳器

    if (pDownloader)

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

        return pDownloader->onWrite(buffer, size, nmemb);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    return 0;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

size_t CDownloader::handleProgress( void *buffer, double dltotal, double dlnow, double ultotal, double ulnow )

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    CDownloader* pDownloader = (CDownloader*) buffer;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

        pDownloader->onProgress(dltotal, dlnow);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

size_t CDownloader::onProgress( const double& dltotal, const double& dlnow )

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    TRACE("%.2f / %.2f (%.2g %%)\n", dlnow, dltotal, dlnow*100.0/dltotal);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

size_t CDownloader::onWrite( void *buffer, size_t size, size_t nmemb )

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    size_t return_size = fwrite(buffer, size, nmemb, m_pFile);

使用libcurl實作的下載下傳器

    //std::cout << (char*) buffer << std::endl;

使用libcurl實作的下載下傳器

    return return_size;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

void CDownloader::onDownload()

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 執行下載下傳

使用libcurl實作的下載下傳器

    CURLcode return_code = CURLE_OK;

使用libcurl實作的下載下傳器

    return_code = curl_easy_perform(m_pCurl);

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 關閉檔案

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 下載下傳失敗

使用libcurl實作的下載下傳器

    if (return_code != CURLE_OK)

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

        return;

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

    // 擷取狀态碼

使用libcurl實作的下載下傳器

    int response_code = 0;

使用libcurl實作的下載下傳器

    curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &response_code);

使用libcurl實作的下載下傳器

    if (response_code != 200)

使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器
使用libcurl實作的下載下傳器

使用示例:

使用libcurl實作的下載下傳器

CDownloader downloader;

使用libcurl實作的下載下傳器

downloader.start("http://xingke.onlinedown.net:82/down/QQ2013SP6.zip", "QQ2013SP6.zip");

使用libcurl實作的下載下傳器

downloader.run();

需要說明的是,這個類本身其實是運作于線程環境下的,是以,加入到多線程環境下,并非難事。擴充或者修改也并不是難得事情,比之WinInet的實作來說,libcurl的實作實在是簡單得無話可說。

繼續閱讀