各位朋友好,第一次在CSDN寫博客,後續時間充足的話會陸續更新一些資源,大家一起探討交流,感謝!!!
如有任何疑問,可以留言。
目的:再次封裝CURL接口,使用FTP相關接口更方便,更易懂
功能: 可支持多線程同時下載,對外接口全封裝在FtpServe子類中(FtpServe繼承CLib_Curl類目的是爲以後便於擴展其他接口協議eg:HTTP等),用戶只需要定義對象,設置好遠程服務器URL和用戶名密碼(也可根據需要改成匿名登錄)即可啓動一個服務來工作。
#ifndef _LIBCURL_H_
#define _LIBCURL_H_
#include <curl/curl.h>
#include <string>
#define QH_Debug(fmt...) do {printf("[%s:%d]: ", __FUNCTION__, __LINE__);printf(fmt);}while(0)
using std::string;
typedef size_t (*HeaderFun_Curl_t)(void *, size_t, size_t, void *);
class CLibcurlCallback
{
public:
virtual void Progress(void* lpParam, double dTotal, double bLoaded) = 0;
};
enum LibcurlFlag
{
Lf_None = 0,
Lf_Download,
Lf_Post,
Lf_Get,
};
typedef enum
{
Un_INIT = 0x00, //未初始化
Err_INIT = 0x01, //初始化失敗
Already_INIT = 0x02, //已初始化
}CURL_GLOBAL_INIT_e;
class CLib_Curl
{
public:
CLib_Curl(void);
~CLib_Curl(void);
inline static CLib_Curl* GetInstance();
bool Set_Timeout(CURL *pstCurl, int s32Second); //設置總執行超時(秒)
bool Set_ConnectTimeout(CURL *pstCurl, int s32Second); //設置連接超時(秒)
bool Set_URL(CURL *pstCurl, const char *pRemoteService); //設置遠程服務地址
bool Set_UserPwd(CURL *pstCurl, const char *pUsrePwd); //設置遠程服務用戶名密碼
bool Set_HeaderFun(CURL *pstCurl, unsigned long *pu32FileSize, HeaderFun_Curl_t pCallBacks); //設置頭處理函數
bool Set_WriteFun(CURL *pstCurl, FILE *pFp, HeaderFun_Curl_t pCallBacks); //設置保存文件函數
bool Set_ResumeFrom(CURL *pstCurl, curl_off_t Pos); //設置斷點續傳起始位置
bool Set_ResumeFromLarge(CURL *pstCurl, curl_off_t Pos); //設置斷點續傳起始位置,針對大文件
bool Set_TransferSpeed(CURL *pstCurl, unsigned long u32Second, unsigned long u32Size); //設置單位時間傳輸速率
bool Set_ProgressBar(CURL *pstCurl, bool bSwitch); //進度條開關 false:關,true:開
bool Set_DebugInfo(CURL *pstCurl, bool bSwitch); //調試信息 false:關,true:開
bool Set_NoBody(CURL *pstCurl, bool bSwitch); //不想在輸出中包含body部分,設置參數爲真
bool CurlInfo_ContentLength(CURL *pstCurl, double *pSize); //獲取文件大小
bool Perform_CurlHandle(CURL *pstCurl); //執行CURL操作
CURL* Init_CurlHandle(void); //初始化curl指針
void Clean_CurlHandle(CURL *pstCurl); //銷燬curl指針
const char* GetError()const; //獲取錯誤詳細信息
public:
protected:
CURLcode m_curlCode;
private:
private:
//static CLib_Curl* m_pInstance;
static pthread_mutex_t m_Mutex;
};
#endif
/************************************************************
*FileName: LibCurl.cpp
*Date: 2019.07.13
*Author: qiuhui
*Version: V1.0
*Description:(LibCURL)庫接口再封裝
*Others:
*History:
***********************************************************/
#include "LibCurl.h"
//CLib_Curl* CLib_Curl::m_pInstance = new CLib_Curl;
CURL_GLOBAL_INIT_e CLib_Curl::m_esInitFlag = Un_INIT;
pthread_mutex_t CLib_Curl::m_Mutex=PTHREAD_MUTEX_INITIALIZER;
CLib_Curl::CLib_Curl(void)
{
pthread_mutex_lock(&m_Mutex);
if (Already_INIT != CLib_Curl::m_esInitFlag)
{
QH_Debug("CURL全局初始化\r\n");
m_curlCode = curl_global_init(CURL_GLOBAL_ALL);
if (CURLE_OK != m_curlCode)
{
CLib_Curl::m_esInitFlag = Err_INIT;
QH_Debug("CURL全局初始化失敗\r\n");
}
else
{
CLib_Curl::m_esInitFlag = Already_INIT;
QH_Debug("CURL全局初始化成功\r\n");
}
}
pthread_mutex_unlock(&m_Mutex);
}
CLib_Curl::~CLib_Curl(void)
{
//curl_global_cleanup(); //整個進程全局只初始化一次,故不考慮析構函數執行curl_global_cleanup()
}
CLib_Curl* CLib_Curl::GetInstance()
{
return NULL;//m_pInstance;
}
bool CLib_Curl::Set_Timeout(CURL *pstCurl, int s32Second)
{
if ((NULL==pstCurl) || (s32Second<0))
{
QH_Debug("parameter Failed:%p,%d\r\n",pstCurl, s32Second);
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_TIMEOUT, s32Second);
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::Set_ConnectTimeout(CURL *pstCurl, int s32Second)
{
if ((NULL==pstCurl) || (s32Second<0))
{
QH_Debug("parameter Failed:%p,%d\r\n",pstCurl, s32Second);
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_CONNECTTIMEOUT, s32Second);
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::Set_URL(CURL *pstCurl, const char *pRemoteService)
{
if ((NULL==pstCurl) || (NULL==pRemoteService))
{
QH_Debug("parameter Failed:%p,%s\r\n",pstCurl, pRemoteService);
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_URL, pRemoteService);
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::Set_UserPwd(CURL *pstCurl, const char *pUsrePwd)
{
if ((NULL==pstCurl) || (NULL==pUsrePwd))
{
QH_Debug("parameter Failed:%p,%s\r\n",pstCurl, pUsrePwd);
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_USERPWD, pUsrePwd);
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::Set_HeaderFun(CURL *pstCurl, unsigned long *pu32FileSize, HeaderFun_Curl_t pCallBacks)
{
if ((NULL==pstCurl) || (NULL==pu32FileSize) || (NULL==pCallBacks))
{
QH_Debug("parameter Failed:%p,%p,%p\r\n",pstCurl, pu32FileSize, pCallBacks);
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_HEADERFUNCTION, pCallBacks);
if (CURLE_OK != m_curlCode)
{
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_HEADERDATA, pu32FileSize);//pu32FileSize->pCallBacks第四個參數賦值
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::Set_WriteFun(CURL *pstCurl, FILE *pFp, HeaderFun_Curl_t pCallBacks)
{
if ((NULL==pstCurl) || (NULL==pFp) || (NULL==pCallBacks))
{
QH_Debug("parameter Failed:%p,%p,%p\r\n",pstCurl, pFp, pCallBacks);
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_WRITEFUNCTION, pCallBacks);
if (CURLE_OK != m_curlCode)
{
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_WRITEDATA, pFp);//要想回調函數保存數據,第3個參數必須是個FILE指針
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::Set_ResumeFrom(CURL *pstCurl, curl_off_t Pos)
{
if ((NULL==pstCurl) || (Pos<0))
{
QH_Debug("parameter Failed:%p,%lld\r\n",pstCurl, Pos);
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_RESUME_FROM, Pos);
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::Set_ResumeFromLarge(CURL *pstCurl, curl_off_t Pos)
{
if ((NULL==pstCurl) || (Pos<0))
{
QH_Debug("parameter Failed:%p,%lld\r\n",pstCurl, Pos);
return false;
}
QH_Debug("Breakpoint Offset:%lld\r\n", Pos);
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_RESUME_FROM_LARGE, Pos);
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::Set_TransferSpeed(CURL *pstCurl, unsigned long u32Second, unsigned long u32Size)
{
if (NULL == pstCurl)
{
QH_Debug("parameter Failed:%p\r\n",pstCurl);
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_LOW_SPEED_TIME, u32Second); //設置時間閥值 單位秒
if (CURLE_OK != m_curlCode)
{
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_LOW_SPEED_LIMIT, u32Size); //設置最低傳輸字節數
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::Set_ProgressBar(CURL *pstCurl, bool bSwitch)
{
if (NULL == pstCurl)
{
QH_Debug("parameter Failed:%p\r\n",pstCurl);
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_NOPROGRESS, (bSwitch==true?0L:1L));
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::Set_DebugInfo(CURL *pstCurl, bool bSwitch)
{
if (NULL == pstCurl)
{
QH_Debug("parameter Failed:%p\r\n",pstCurl);
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_VERBOSE, (bSwitch==false?0L:1L));
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::Set_NoBody(CURL *pstCurl, bool bSwitch)
{
if ((NULL == pstCurl))
{
QH_Debug("parameter Failed:%p\r\n",pstCurl);
return false;
}
m_curlCode = curl_easy_setopt(pstCurl, CURLOPT_NOBODY, (bSwitch==false?0L:1L));
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::CurlInfo_ContentLength(CURL *pstCurl, double *pSize)
{
if ((NULL==pstCurl) || (NULL==pSize))
{
QH_Debug("parameter Failed:%p,%p\r\n",pstCurl,pSize);
return false;
}
m_curlCode = curl_easy_getinfo(pstCurl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, pSize);
return CURLE_OK == m_curlCode;
}
bool CLib_Curl::Perform_CurlHandle(CURL *pstCurl)
{
if (NULL == pstCurl)
{
QH_Debug("parameter Failed:%p\r\n",pstCurl);
return false;
}
m_curlCode= curl_easy_perform(pstCurl);
QH_Debug("m_curlCode:%d\r\n",m_curlCode);
return CURLE_OK == m_curlCode;
}
CURL* CLib_Curl::Init_CurlHandle(void)
{
return curl_easy_init();
}
void CLib_Curl::Clean_CurlHandle(CURL *pstCurl)
{
if (NULL == pstCurl)
{
QH_Debug("parameter Failed:%p\r\n",pstCurl);
return;
}
curl_easy_cleanup(pstCurl);
}
const char* CLib_Curl::GetError()const
{
return curl_easy_strerror(m_curlCode);
}
#ifndef _FTPINTERFACE_H_
#define _FTPINTERFACE_H_
#include "LibCurl.h"
using std::string;
typedef enum
{
FTP_Work =0x00, //工作
FTP_Free =0x01, //退出
}FTP_Run_Status_e;
typedef enum
{
UnKnown_Ftp_Mode = -1,
Ftp_File_Upload = 0x00, //文件上傳
Ftp_Dir_Upload = 0x00, //目錄上傳
Ftp_File_Download = 0x01, //文件下載
Ftp_Dir_Download = 0x01, //目錄下載
}FTP_Operat_Mode_e;
typedef enum
{
Ftp_Local_err =-1, //ftp內部異常,不以這個爲結束標準
Ftp_Ok =0x00, //成功
Ftp_LocalPath_Fail =0x01, //終端本地路徑異常
Ftp_RemotePath_Fail =0x02, //遠程服務路徑異常
Ftp_Disk_SpaceHungry =0x03, //設備磁盤空間不足
Ftp_UnKnown_WorkMode =0x04, //未知的ftp工作模式
Ftp_Connect_Fail =0x05, //連接失敗
Ftp_Login_Denied =0x06, //登錄失敗
Ftp_Memory_Fail =0x07, //內存分配請求失敗
Ftp_GetFile_Fail =0x08, //獲取文件錯誤
Ftp_Service_Anomaly =0x09, //ftp服務器異常
Ftp_Url_Error =0x0A, //ftp遠程地址不正確
Ftp_Unkown_error =0xFF, //ftp未知錯誤
}FTP_Code_e;
typedef struct
{
string strUrl;
string strUsrePass;
}FTP_Remote_Usre_s;
typedef struct
{
unsigned long u32Second; //單位秒
unsigned long u32Size; //單位字節
}FTP_Transfer_Contrl_s;
class FtpServe:public CLib_Curl
{
public:
FtpServe(FTP_Operat_Mode_e eMode, FTP_Remote_Usre_s stRemote, string strLocalPath, int s32TimeOut=10, FTP_Transfer_Contrl_s stTraCrl=m_sstTraCrl);
~FtpServe();
void Ftp_StartServe();
FTP_Code_e Ftp_GetCode(void);
FTP_Run_Status_e Ftp_GetRunStatus(void);
public:
private:
void* Ftp_ServeThread(void *pParm);
FTP_Code_e Ftp_Convert_CurlCode(void);
FTP_Code_e Ftp_Download(FTP_Operat_Mode_e eMode);
FTP_Code_e Ftp_FileDownload(FTP_Operat_Mode_e eMode);
FTP_Code_e Ftp_CheckPathValid(FTP_Operat_Mode_e eMode, const char *pInRemotePath, const char *pInLocalPath, char *pOutDirPath, int s32Size);
unsigned int Ftp_CheckDiskSpace(const char *pPath);
unsigned int Ftp_AvailableDisk(const char * pcDir) const;
unsigned int Ftp_GetRemoteFileSize(void);
static size_t Get_ContentLength(void *ptr, size_t size, size_t nmemb, void *stream);
static size_t WriteFile_Func(void *ptr, size_t size, size_t nmemb, void *stream);
private:
THREAD_STATUS_S m_stFtpThread_status;
CURL *m_pCurl;
FTP_Code_e m_eFtpCode;
FTP_Operat_Mode_e m_eWorkMode;
FTP_Remote_Usre_s m_stRemoteUser;
FTP_Transfer_Contrl_s m_stTraCrl; //傳輸控制(單位時間低於傳輸字節數則退出)
static const FTP_Transfer_Contrl_s m_sstTraCrl;
string m_strDevLocalPath; //主機本地路徑
int m_s32Timeout; //連接超時時間
};
#endif
/************************************************************
*FileName: FtpInterface.cpp
*Date: 2019.07.13
*Author: qiuhui
*Version: V1.0
*Description:基於curl庫封裝的ftp接口
*Others:TODO:上傳和目錄下載未完善
*History:
***********************************************************/
#include "FtpInterface.h"
const FTP_Transfer_Contrl_s FtpServe::m_sstTraCrl = {30, 5};
FtpServe::FtpServe(FTP_Operat_Mode_e eMode,FTP_Remote_Usre_s stRemote,string strLocalPath,\
int s32TimeOut,FTP_Transfer_Contrl_s stTraCrl)
:m_eWorkMode(eMode)
,m_stRemoteUser(stRemote)
,m_strDevLocalPath(strLocalPath)
,m_s32Timeout(s32TimeOut)
,m_stTraCrl(stTraCrl)
{
/* 初始化curl */
m_pCurl = Init_CurlHandle();
m_eFtpCode = Ftp_Ok;
memset(&m_stFtpThread_status, 0, sizeof(m_stFtpThread_status));
}
FtpServe::~FtpServe(void)
{
/* 銷燬 */
Clean_CurlHandle(m_pCurl);
}
void* FtpServe::Ftp_ServeThread(void *pParm)
{
QH_Debug("%s start,pthread_id:%u\r\n",m_stFtpThread_status.ThreadName, m_stFtpThread_status.pid);
//while(true == m_stFtpThread_status.bThreadStart)
{
if ((Ftp_File_Upload==m_eWorkMode) || (Ftp_Dir_Upload==m_eWorkMode))
{
QH_Debug("FtpServe workMode Download:%d\r\n",m_eWorkMode);
}
else if ((Ftp_File_Download==m_eWorkMode) || (Ftp_Dir_Download==m_eWorkMode))
{
QH_Debug("FtpServe workMode Upload:%d\r\n",m_eWorkMode);
m_eFtpCode = Ftp_Download(m_eWorkMode);
}
else
{
m_eFtpCode = Ftp_UnKnown_WorkMode;
QH_Debug("FtpServe workMode Fail:%d\r\n",m_eWorkMode);
}
msleep(500);
}
m_stFtpThread_status.bThreadStart = false;
QH_Debug("%s exit\r\n", m_stFtpThread_status.ThreadName);
pthread_exit(NULL);
}
void FtpServe::Ftp_StartServe()
{
if(false == m_stFtpThread_status.bThreadStart)
{
m_stFtpThread_status.bThreadStart = true;
m_stFtpThread_status.ThreadName = "FtpServe_thread";
if(0 == pthread_create(&m_stFtpThread_status.pid, NULL, (void*(*)(void*))&FtpServe::Ftp_ServeThread, this))
{
pthread_detach(m_stFtpThread_status.pid);
}
else
{
m_stFtpThread_status.bThreadStart = false;
}
msleep(100);
}
}
FTP_Code_e FtpServe::Ftp_Download(FTP_Operat_Mode_e eMode)
{
if (Ftp_File_Download == eMode)
{
return Ftp_FileDownload(eMode);
}
else if (Ftp_Dir_Download == eMode)
{
//TODO
}
}
FTP_Code_e FtpServe::Ftp_FileDownload(FTP_Operat_Mode_e eMode)
{
curl_off_t l_LocalFileLen = -1;
FTP_Code_e l_eCode = Ftp_Ok;
FILE *l_pFp = NULL;
struct stat l_stfile_info;
char l_s8DirPath[256] = {0};
unsigned long l_u32FileSize = 0;
unsigned long l_u32DiskSpace = 0;
bool l_bFlag = false;
memset(l_s8DirPath, 0, sizeof(l_s8DirPath));
l_eCode = Ftp_CheckPathValid(eMode, m_stRemoteUser.strUrl.c_str(), m_strDevLocalPath.c_str(), l_s8DirPath, sizeof(l_s8DirPath));
if (Ftp_Ok != l_eCode)
{
QH_Debug("Path Check error:%d\r\n", l_eCode);
return l_eCode;
}
/* 獲取本地文件大小信息 */
if(stat(m_strDevLocalPath.c_str(), &l_stfile_info) == 0)
{
l_LocalFileLen = l_stfile_info.st_size;
l_bFlag = true;
}
/* 檢測目錄空間大小 */
l_u32DiskSpace = Ftp_CheckDiskSpace(l_s8DirPath);
l_u32FileSize = Ftp_GetRemoteFileSize();
if (l_u32FileSize >= l_u32DiskSpace)
{
QH_Debug("Disk Space Hungry!!!\r\n");
return Ftp_Disk_SpaceHungry;
}
/* 追加方式打開文件,實現斷點續傳 */
l_pFp = fopen(m_strDevLocalPath.c_str(), "ab+");
if (NULL == l_pFp)
{
QH_Debug("open:%s Failed,Error message:%s\r\n",m_strDevLocalPath.c_str(), strerror(errno));
return Ftp_LocalPath_Fail;
}
/* 開始下載 */
Set_URL(m_pCurl, m_stRemoteUser.strUrl.c_str());
Set_UserPwd(m_pCurl, m_stRemoteUser.strUsrePass.c_str());
Set_ConnectTimeout(m_pCurl, m_s32Timeout);
/* 沒用到http方式,頭函數暫時不設置,注意回調函數要麼靜態,不要調用非靜態成員函數 */
//l_u32FileSize = 0;
//Set_HeaderFun(m_pCurl, &l_u32FileSize, (HeaderFun_Curl_t)FtpServe::Get_ContentLength);
/* 設置斷點續傳 */
Set_ResumeFromLarge(m_pCurl, l_bFlag==true?l_LocalFileLen:0);
Set_WriteFun(m_pCurl, l_pFp, (HeaderFun_Curl_t)&FtpServe::WriteFile_Func);
Set_TransferSpeed(m_pCurl, m_stTraCrl.u32Second, m_stTraCrl.u32Size);
Set_ProgressBar(m_pCurl, false);
Set_DebugInfo(m_pCurl, true);
if (true == Perform_CurlHandle(m_pCurl))
{
fclose(l_pFp);
return Ftp_Ok;
}
else
{
QH_Debug("File Download Failed,error:%s\r\n",GetError());
fclose(l_pFp);
return Ftp_Convert_CurlCode();
}
}
unsigned int FtpServe::Ftp_GetRemoteFileSize(void)
{
CURL* l_Curl;
CURLcode res;
unsigned long l_u32FileSize = 0;
bool l_bRet = false;
l_Curl = Init_CurlHandle();
if (l_Curl)
{
Set_URL(l_Curl, m_stRemoteUser.strUrl.c_str());
Set_UserPwd(l_Curl, m_stRemoteUser.strUsrePass.c_str());
/* 連接超時設置 */
Set_ConnectTimeout(l_Curl, m_s32Timeout);
Set_NoBody(l_Curl, true);
Set_DebugInfo(l_Curl, true);
if (true == Perform_CurlHandle(l_Curl))
{
double l_Size = 0.0;
l_bRet = CurlInfo_ContentLength(l_Curl, &l_Size);//第二個參數必須爲(double*)否則會段錯誤
if ((true==l_bRet) && (l_Size>=0))
{
l_u32FileSize = (unsigned long)l_Size;
QH_Debug("Url:%s size:%ld[%0.0f]bytes\r\n",m_stRemoteUser.strUrl.c_str(), l_u32FileSize, l_Size);
}
else
{
QH_Debug("CurlInfo_ContentLength Failed,error:%s\r\n",GetError());
}
}
else
{
Ftp_Convert_CurlCode();
QH_Debug("Get Remote File size Failed curlCode:%d,%s\r\n",m_curlCode,GetError());
}
Clean_CurlHandle(l_Curl);
}
return l_u32FileSize;
}
FTP_Code_e FtpServe::Ftp_CheckPathValid(FTP_Operat_Mode_e eMode, const char *pInRemotePath, const char *pInLocalPath, char *pOutDirPath, int s32Size)
{
if (Ftp_File_Download == eMode)
{
if (('/'==pInRemotePath[strlen(pInRemotePath)-1]) || (NULL==pInRemotePath))
{
return Ftp_RemotePath_Fail;
}
if (('/'==pInLocalPath[strlen(pInLocalPath)-1]) || (NULL==pInLocalPath))
{
return Ftp_LocalPath_Fail;
}
if (NULL != pOutDirPath)
{
char *l_pAddr = NULL;
if (NULL != (l_pAddr=_Strrstr((char *)pInLocalPath, (char *)"/")))
{
char l_s32MaxLen = (l_pAddr-pInLocalPath+1)>=s32Size?s32Size-1:(l_pAddr-pInLocalPath+1);
memcpy(pOutDirPath, pInLocalPath, l_s32MaxLen);
}
}
}
else if (Ftp_Dir_Download == eMode)
{
if (('/'!=pInRemotePath[strlen(pInRemotePath)-1]) || (NULL==pInRemotePath))
{
return Ftp_RemotePath_Fail;
}
if (('/'!=pInLocalPath[strlen(pInLocalPath)-1]) || (NULL==pInLocalPath))
{
return Ftp_LocalPath_Fail;
}
if (NULL != pOutDirPath)
{
snprintf(pOutDirPath, s32Size, "%s", pInLocalPath);
QH_Debug("Out Dirpath:%s\r\n", pOutDirPath);
}
}
if (0 != access(pOutDirPath, F_OK))
{
if (0 > _MakeDirs(pOutDirPath))
{
QH_Debug("Creat Dir Error:%s\r\n", pOutDirPath);
return Ftp_LocalPath_Fail;
}
}
return Ftp_Ok;
}
unsigned int FtpServe::Ftp_AvailableDisk(const char *ps8Dir) const
{
if(NULL == ps8Dir)
return 0;
struct statfs diskInfo;
unsigned int blocksize = 0; //每個block裏包含的字節數
unsigned int availableDisk = 0; //可用空間大小
int iRet = -1;
iRet = statfs(ps8Dir, &diskInfo);
if(0 == iRet)
{
blocksize = diskInfo.f_bsize;
availableDisk = diskInfo.f_bavail * blocksize;//(byte)
}
QH_Debug("Current Dir Path:%s,available:%u\r\n", ps8Dir, availableDisk);
return availableDisk;
}
unsigned int FtpServe::Ftp_CheckDiskSpace(const char *pPath)
{
unsigned int l_u32Ret = 0;
unsigned int i = 0;
char l_s8pDirName[2][20]={"/data/", "/var/"};
if (NULL == pPath)
{
l_u32Ret = 0;
return l_u32Ret;
}
for (i=0; i<sizeof(l_s8pDirName)/sizeof(l_s8pDirName[0]); i++)
{
if (NULL != strstr(pPath, l_s8pDirName[i]))
{
break;
}
}
if (i >= sizeof(l_s8pDirName)/sizeof(l_s8pDirName[0]))
{
l_u32Ret = 0;
return l_u32Ret;
}
return Ftp_AvailableDisk(l_s8pDirName[i]);
}
FTP_Code_e FtpServe::Ftp_GetCode(void)
{
return m_eFtpCode;
}
FTP_Code_e FtpServe::Ftp_Convert_CurlCode(void)
{
switch (m_curlCode)
{
case CURLE_OK: //成功
m_eFtpCode = Ftp_Ok;
break;
case CURLE_OPERATION_TIMEDOUT:
case CURLE_COULDNT_CONNECT: //連接失敗
m_eFtpCode = Ftp_Connect_Fail;
break;
case CURLE_LOGIN_DENIED: //登錄失敗
m_eFtpCode = Ftp_Login_Denied;
break;
case CURLE_REMOTE_ACCESS_DENIED:
case CURLE_FTP_ACCEPT_FAILED:
case CURLE_FTP_WEIRD_PASV_REPLY:
case CURLE_FTP_WEIRD_227_FORMAT:
m_eFtpCode = Ftp_Service_Anomaly; //ftp服務器異常(暫時這樣,不一定是服務器異常,還可以細分)
break;
case CURLE_PARTIAL_FILE:
case CURLE_WRITE_ERROR:
case CURLE_BAD_DOWNLOAD_RESUME:
case CURLE_RECV_ERROR:
case CURLE_TFTP_NOTFOUND:
case CURLE_REMOTE_FILE_NOT_FOUND:
m_eFtpCode = Ftp_GetFile_Fail; //ftp獲取文件錯誤(暫時這樣,不一定是獲取文件錯誤,還可以細分)
break;
case CURLE_OUT_OF_MEMORY:
m_eFtpCode = Ftp_Memory_Fail; //內存分配請求失敗
break;
case CURLE_URL_MALFORMAT:
m_eFtpCode = Ftp_Url_Error; //網址的格式不正確
break;
default :
m_eFtpCode = Ftp_Unkown_error; //未知錯誤
break;
}
return m_eFtpCode;
}
FTP_Run_Status_e FtpServe::Ftp_GetRunStatus(void)
{
if (true == m_stFtpThread_status.bThreadStart)
{
return FTP_Work;
}
else
{
return FTP_Free;
}
}
/* 解析頭部長度 Content-Length */
size_t FtpServe::Get_ContentLength(void *ptr, size_t size, size_t nmemb, void *stream)
{
int l_s32Ret;
long l_s32len = 0;
l_s32Ret = sscanf((const char*)ptr, "Content-Length: %ld\n", &l_s32len);
if (l_s32Ret) /* Microsoft: we don't read the specs */
{
*((unsigned long *) stream) = l_s32len;
QH_Debug("%s,%lu\r\n", ptr, *((unsigned long *) stream));
}
return size * nmemb;
}
/* 將接收數據寫入FIFE* */
size_t FtpServe:: WriteFile_Func(void *ptr, size_t size, size_t nmemb, void *stream)
{
return fwrite(ptr, size, nmemb, (FILE*)stream);
}
#include "FtpInterface.h"
int main(int argc,char** argv)
{
FTP_Remote_Usre_s l_stUsrePasswd;
FTP_Transfer_Contrl_s l_stTraCrl;
l_stUsrePasswd.strUrl = "ftp://ip:port/filepath";
l_stUsrePasswd.strUsrePass = "xxxxxxx";
FtpServe l_FtpServe(Ftp_File_Download, l_stUsrePasswd, (char *)"/var/test1");
l_FtpServe.Ftp_StartServe();
l_stUsrePasswd.strUrl = "ftp://ip:port/filepath";
FtpServe l_FtpServe11(Ftp_File_Download, l_stUsrePasswd, (char *)"/var/test2");
l_FtpServe11.Ftp_StartServe();
l_stUsrePasswd.strUrl = "ftp://ip:port/filepath";
FtpServe l_FtpServe22(Ftp_File_Download, l_stUsrePasswd, (char *)"/var/test3");
l_FtpServe22.Ftp_StartServe();
l_stTraCrl.u32Second = 10;
l_stTraCrl.u32Size = 20;
l_stUsrePasswd.strUrl = "ftp://ip:port/filepath";
FtpServe l_FtpServe33(Ftp_File_Download, l_stUsrePasswd, (char *)"/var/test4",20, l_stTraCrl);
l_FtpServe33.Ftp_StartServe();
l_stUsrePasswd.strUrl = "ftp://ip:port/filepath";
FtpServe l_FtpServe44(Ftp_File_Download, l_stUsrePasswd, (char *)"/var/test5", 20, l_stTraCrl);
l_FtpServe44.Ftp_StartServe();
while ((FTP_Work==l_FtpServe.Ftp_GetRunStatus())\
||(FTP_Work==l_FtpServe11.Ftp_GetRunStatus())
||(FTP_Work==l_FtpServe22.Ftp_GetRunStatus())
||(FTP_Work==l_FtpServe33.Ftp_GetRunStatus())
||(FTP_Work==l_FtpServe44.Ftp_GetRunStatus()))
{
msleep(3000);
QH_Debug("Wait:%dsecond\r\n", l_cout+=3);
}
QH_Debug("result:%d\r\n", l_FtpServe.Ftp_GetCode());
QH_Debug("result:%d\r\n", l_FtpServe11.Ftp_GetCode());
QH_Debug("result:%d\r\n", l_FtpServe22.Ftp_GetCode());
QH_Debug("result:%d\r\n", l_FtpServe33.Ftp_GetCode());
QH_Debug("result:%d\r\n", l_FtpServe44.Ftp_GetCode());
}