各位朋友好,第一次在优快云写博客,后续时间充足的话会陆续更新一些资源,大家一起探讨交流,感谢!!!
如有任何疑问,可以留言。
目的:再次封装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());
}