使用libcurl實現的上傳器
頭文件
/**********************************************************************
* Copyright (C) 2014 - - All Rights Reserved
*
* 文件名稱: Uploader_LibCurl.h
* 摘 要: 上傳器 - LibCurl實現
*
* 作 者: yanglinbo,
* 修 改: 查看文件最下方.
*
***********************************************************************/

#ifndef __Uploader_LibCurl_H__
#define __Uploader_LibCurl_H__


#include <curl/curl.h>
#include <fstream>
#include <string>


class CUploader
{
public:
CUploader(void);
virtual ~CUploader(void);

public:
/// 線程入口函數
virtual bool run();

/// 啟動上傳
virtual bool start(const std::string& strUrl, const std::string& strLocalFile);

/// 停止上傳
virtual bool stop();

/// 是否運行狀態
bool isRunning() const;

protected:
/// 讀取回調
static size_t handleRead(void *buffer, size_t size, size_t nmemb, void *userp);

/// 進度回調
static size_t handleProgress(void *buffer, double dltotal, double dlnow, double ultotal, double ulnow);

protected:
/// 讀取回調
size_t onUpload(void *buffer, size_t size, size_t nmemb);

/// 進度回調
size_t onProgress(const double& ultotal, const double& ulnow);

/// 上傳回調
void onUpload();

protected:
/// 設置libcurl選項
bool setOption();

/// 清除數據
void clear();

protected:
CURL* m_pCurl; ///< libcurl句柄
FILE* m_pFile; ///< 文件指針

bool m_bRunning; ///< 運行標志

std::string m_strRemoteUrl; ///< 遠程鏈接
std::string m_strLocalFilePath; ///< 本地文件路徑

size_t m_nLocalFileSize; ///< 本地文件大小
};


#endif

實現文件
/**********************************************************************
* Copyright (C) 2014 - - All Rights Reserved
*
* 文件名稱: Uploader_LibCurl.cpp
* 摘 要: 上傳器 - LibCurl實現
*
* 作 者: yanglinbo,
* 修 改: 查看文件最下方.
*
***********************************************************************/

#include "StdAfx.h"
#include "Uploader.h"
#include <sys/stat.h>
#include <fcntl.h>


CUploader::CUploader(void)
: m_pCurl(NULL)
, m_pFile(NULL)
, m_bRunning(false)
, m_nLocalFileSize(0)
{
}

CUploader::~CUploader(void)
{
stop();
}

bool CUploader::run()
{
onUpload();
return true;
}

bool CUploader::isRunning() const
{
return m_bRunning;
}

void CUploader::clear()
{
if (m_pFile)
{
fclose(m_pFile);
m_pFile = NULL;
}

if (m_pCurl)
{
curl_easy_cleanup(m_pCurl);
m_pCurl = NULL;
curl_global_cleanup();
}

m_strRemoteUrl.clear();
m_strLocalFilePath.clear();

m_nLocalFileSize = 0;
}

bool CUploader::setOption()
{
// 遠程URL,支持 http, https, ftp
curl_easy_setopt(m_pCurl, CURLOPT_URL, m_strRemoteUrl.c_str());

curl_easy_setopt(m_pCurl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)m_nLocalFileSize);

// 設置User-Agent
std::string useragent = _T("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1");
curl_easy_setopt(m_pCurl, CURLOPT_USERAGENT, useragent.c_str());

// 設置重定向的最大次數
curl_easy_setopt(m_pCurl, CURLOPT_MAXREDIRS, 5);

// 設置301、302跳轉跟隨location
curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1);

curl_easy_setopt(m_pCurl, CURLOPT_UPLOAD, TRUE);

curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(m_pCurl, CURLOPT_POST, TRUE);
curl_easy_setopt(m_pCurl, CURLOPT_FORBID_REUSE, TRUE);

// 上傳內容回調函數
curl_easy_setopt(m_pCurl, CURLOPT_READFUNCTION, handleRead);
curl_easy_setopt(m_pCurl, CURLOPT_READDATA, this);

// 進度回調函數
curl_easy_setopt(m_pCurl, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSDATA, this);
curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSFUNCTION, handleProgress);

// 跳過服務器SSL驗證,不使用CA證書
curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 0L);

// 驗證服務器端發送的證書,默認是 2(高),1(中),0(禁用)
curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, 0L);

return true;
}

bool CUploader::start(const std::string& strUrl, const std::string& strLocalFile)
{
if (strUrl.empty()) return false;

if (m_bRunning == true) return true;

clear();

m_strRemoteUrl = strUrl;
m_strLocalFilePath = strLocalFile;

// 打開文件
m_pFile = fopen(m_strLocalFilePath.c_str(), "rb");
if (m_pFile == NULL)
{
return false;
}

// 獲取文件大小
struct stat file_info;
if (fstat(fileno(m_pFile), &file_info) != 0)
{
return false;
}
m_nLocalFileSize = file_info.st_size;

// 初始化libcurl
m_pCurl = curl_easy_init();
if (m_pCurl == NULL)
{
return false;
}

// 設置libcurl的選項
setOption();

m_bRunning = true;

return true;
}

bool CUploader::stop()
{
clear();

m_bRunning = false;

return true;
}

size_t CUploader::handleRead( void *buffer, size_t size, size_t nmemb, void *userp )
{
CUploader* pDownloader = (CUploader*) userp;
if (pDownloader)
{
return pDownloader->onUpload(buffer, size, nmemb);
}
return 0;
}

size_t CUploader::handleProgress( void *buffer, double dltotal, double dlnow, double ultotal, double ulnow )
{
CUploader* pDownloader = (CUploader*) buffer;
if (pDownloader)
{
pDownloader->onProgress(ultotal, ulnow);
}
return 0;
}

size_t CUploader::onProgress( const double& ultotal, const double& ulnow )
{
TRACE("%.2f / %.2f (%.2g %%)\n", ulnow, ultotal, ulnow*100.0/ultotal);
return 0;
}

size_t CUploader::onUpload( void *buffer, size_t size, size_t nmemb )
{
size_t return_size = fread(buffer, size, nmemb, m_pFile);
return return_size;
}

void CUploader::onUpload()
{
// 執行上傳
CURLcode return_code = CURLE_OK;
return_code = curl_easy_perform(m_pCurl);

// 關閉文件
if (m_pFile)
{
fclose(m_pFile);
m_pFile = NULL;
}

// 上傳失敗
if (return_code != CURLE_OK)
{
return;
}

// 獲取狀態碼
int response_code = 0;
curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &response_code);
}

示例代碼:
CUploader uploader
uploader.start("ftp://upload:upload@127.0.0.1/hello.exe", "C:\\fly.exe");
uploader.run();
/**********************************************************************
* Copyright (C) 2014 - - All Rights Reserved
*
* 文件名稱: Uploader_LibCurl.h
* 摘 要: 上傳器 - LibCurl實現
*
* 作 者: yanglinbo,
* 修 改: 查看文件最下方.
*
***********************************************************************/
#ifndef __Uploader_LibCurl_H__
#define __Uploader_LibCurl_H__

#include <curl/curl.h>
#include <fstream>
#include <string>

class CUploader
{
public:
CUploader(void);
virtual ~CUploader(void);
public:
/// 線程入口函數
virtual bool run();
/// 啟動上傳
virtual bool start(const std::string& strUrl, const std::string& strLocalFile);
/// 停止上傳
virtual bool stop();
/// 是否運行狀態
bool isRunning() const;
protected:
/// 讀取回調
static size_t handleRead(void *buffer, size_t size, size_t nmemb, void *userp);
/// 進度回調
static size_t handleProgress(void *buffer, double dltotal, double dlnow, double ultotal, double ulnow);
protected:
/// 讀取回調
size_t onUpload(void *buffer, size_t size, size_t nmemb);
/// 進度回調
size_t onProgress(const double& ultotal, const double& ulnow);
/// 上傳回調
void onUpload();
protected:
/// 設置libcurl選項
bool setOption();
/// 清除數據
void clear();
protected:
CURL* m_pCurl; ///< libcurl句柄
FILE* m_pFile; ///< 文件指針
bool m_bRunning; ///< 運行標志
std::string m_strRemoteUrl; ///< 遠程鏈接
std::string m_strLocalFilePath; ///< 本地文件路徑
size_t m_nLocalFileSize; ///< 本地文件大小
};

#endif
實現文件
/**********************************************************************
* Copyright (C) 2014 - - All Rights Reserved
*
* 文件名稱: Uploader_LibCurl.cpp
* 摘 要: 上傳器 - LibCurl實現
*
* 作 者: yanglinbo,
* 修 改: 查看文件最下方.
*
***********************************************************************/
#include "StdAfx.h"
#include "Uploader.h"
#include <sys/stat.h>
#include <fcntl.h>

CUploader::CUploader(void)
: m_pCurl(NULL)
, m_pFile(NULL)
, m_bRunning(false)
, m_nLocalFileSize(0)
{
}
CUploader::~CUploader(void)
{
stop();
}
bool CUploader::run()
{
onUpload();
return true;
}
bool CUploader::isRunning() const
{
return m_bRunning;
}
void CUploader::clear()
{
if (m_pFile)
{
fclose(m_pFile);
m_pFile = NULL;
}
if (m_pCurl)
{
curl_easy_cleanup(m_pCurl);
m_pCurl = NULL;
curl_global_cleanup();
}
m_strRemoteUrl.clear();
m_strLocalFilePath.clear();
m_nLocalFileSize = 0;
}
bool CUploader::setOption()
{
// 遠程URL,支持 http, https, ftp
curl_easy_setopt(m_pCurl, CURLOPT_URL, m_strRemoteUrl.c_str());
curl_easy_setopt(m_pCurl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)m_nLocalFileSize);
// 設置User-Agent
std::string useragent = _T("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1");
curl_easy_setopt(m_pCurl, CURLOPT_USERAGENT, useragent.c_str());
// 設置重定向的最大次數
curl_easy_setopt(m_pCurl, CURLOPT_MAXREDIRS, 5);
// 設置301、302跳轉跟隨location
curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(m_pCurl, CURLOPT_UPLOAD, TRUE);
curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(m_pCurl, CURLOPT_POST, TRUE);
curl_easy_setopt(m_pCurl, CURLOPT_FORBID_REUSE, TRUE);
// 上傳內容回調函數
curl_easy_setopt(m_pCurl, CURLOPT_READFUNCTION, handleRead);
curl_easy_setopt(m_pCurl, CURLOPT_READDATA, this);
// 進度回調函數
curl_easy_setopt(m_pCurl, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSDATA, this);
curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSFUNCTION, handleProgress);
// 跳過服務器SSL驗證,不使用CA證書
curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 0L);
// 驗證服務器端發送的證書,默認是 2(高),1(中),0(禁用)
curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, 0L);
return true;
}
bool CUploader::start(const std::string& strUrl, const std::string& strLocalFile)
{
if (strUrl.empty()) return false;
if (m_bRunning == true) return true;
clear();
m_strRemoteUrl = strUrl;
m_strLocalFilePath = strLocalFile;
// 打開文件
m_pFile = fopen(m_strLocalFilePath.c_str(), "rb");
if (m_pFile == NULL)
{
return false;
}
// 獲取文件大小
struct stat file_info;
if (fstat(fileno(m_pFile), &file_info) != 0)
{
return false;
}
m_nLocalFileSize = file_info.st_size;
// 初始化libcurl
m_pCurl = curl_easy_init();
if (m_pCurl == NULL)
{
return false;
}
// 設置libcurl的選項
setOption();
m_bRunning = true;
return true;
}
bool CUploader::stop()
{
clear();
m_bRunning = false;
return true;
}
size_t CUploader::handleRead( void *buffer, size_t size, size_t nmemb, void *userp )
{
CUploader* pDownloader = (CUploader*) userp;
if (pDownloader)
{
return pDownloader->onUpload(buffer, size, nmemb);
}
return 0;
}
size_t CUploader::handleProgress( void *buffer, double dltotal, double dlnow, double ultotal, double ulnow )
{
CUploader* pDownloader = (CUploader*) buffer;
if (pDownloader)
{
pDownloader->onProgress(ultotal, ulnow);
}
return 0;
}
size_t CUploader::onProgress( const double& ultotal, const double& ulnow )
{
TRACE("%.2f / %.2f (%.2g %%)\n", ulnow, ultotal, ulnow*100.0/ultotal);
return 0;
}
size_t CUploader::onUpload( void *buffer, size_t size, size_t nmemb )
{
size_t return_size = fread(buffer, size, nmemb, m_pFile);
return return_size;
}
void CUploader::onUpload()
{
// 執行上傳
CURLcode return_code = CURLE_OK;
return_code = curl_easy_perform(m_pCurl);
// 關閉文件
if (m_pFile)
{
fclose(m_pFile);
m_pFile = NULL;
}
// 上傳失敗
if (return_code != CURLE_OK)
{
return;
}
// 獲取狀態碼
int response_code = 0;
curl_easy_getinfo(m_pCurl, CURLINFO_RESPONSE_CODE, &response_code);
}
示例代碼:
CUploader uploader
uploader.start("ftp://upload:upload@127.0.0.1/hello.exe", "C:\\fly.exe");
uploader.run();posted on 2014-04-01 23:23 楊粼波 閱讀(1257) 評論(0) 編輯 收藏 引用 所屬分類: 網絡編程 、C++




