各位朋友好,第一次在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());
}

libcurl开源库封装ftp工具,支持多线程并发、断点续传、超时连接、传输速率控制相关推荐

  1. Siege(开源Web压力测试工具)——多线程编程最佳实例

    在英语中,"Siege"意为围攻.包围.同时Siege也是一款使用纯C语言编写的开源WEB压测工具,适合在GNU/Linux上运行,并且具有较强的可移植性.之所以说它是多线程编程的 ...

  2. 使用libcurl开源库和Duilib做的下载文件并显示进度条的小工具

    转载:http://blog.csdn.net/mfcing/article/details/43603525 转载:http://blog.csdn.net/infoworld/article/de ...

  3. Meta 开源早期 AI 翻译工具支持 200 种语言

    编译 | 禾木木 出品 | AI科技大本营(ID:rgznai100) Meta 创建了一个能够翻译 200 种不同语言的人工智能模型,包括许多目前商业工具不支持的语言.Meta 正在开源该项目,希望 ...

  4. 基于 Multitype 开源库封装更好用的RecyclerView.Adapter

    前言 MultiType 这个项目,至今 v3.x 稳定多时,考虑得非常多,但也做得非常克制.原则一直是 直观.灵活.可靠.简单纯粹(其中直观和灵活是非常看重的). 这是 MultiType 框架作者 ...

  5. C++ 使用libwebsockets开源库封装client类

    本文参考:封装利用libwebsockets写出的客户端.服务端程序为客户端服务端类_逍遥游的博客-CSDN博客_libwebsockets封装 最近项目需要使用C++连接websocket服务器,选 ...

  6. VC++调用libcurl开源库实现发送邮件的功能(附源码)

    目录 1.为啥要选择libcurl库去实现邮件的发送 2.调用libcurl库的API接口实现邮件发送

  7. 这些Android开源库可以让你的逼格再升一个level

    热文导读 | 点击标题阅读 金九银十跳槽季如何进阶找到合适满意的工作? JVM完全指南 2019届互联网校招薪资出炉!TMD整体超越 BAT.华为 来源:http://www.apkbus.com/b ...

  8. ftp 工具_ftp工具,ftp工具有哪些

    对于ftp工具,你了解多少?其实一般人也接触不到这种软件.ftp工具主要是针对从事网站管理的工作人员比较有利的一款工具.可以帮助他们快速的解决工作中的问题.方便.简单.快捷又明了的解决问题.那ftp工 ...

  9. ftp 工具_ftp,win7的ftp工具

    你知道有哪些能用win7系统使用的ftp工具吗?因为现在的ftp工具其实限制很多的,有的只能在windows系统上使用,有的只能在linux系统上使用.很少有能两种都兼容的,所以需要找到一款着这样的f ...

最新文章

  1. 厦门理工学院2019年数据结构与算法考研初试大纲
  2. 小程序生成海报 详解
  3. OpenGL函数:wglCreateContext
  4. MPEG的完整形式是什么?
  5. 2021中国到店消费新趋势洞察报告
  6. android开发所遇问题集(一)----Mr.Zhang
  7. Android重写View并且自定义属性(二)
  8. [转]当你老了,一生最后悔什么?全球统计前五名!
  9. win11资源管理器卡顿怎么办 Windows11解决资源管理器卡顿的步骤方法
  10. STEP 7 Micro/WIN 指令库下载网址大全s7-200
  11. eos java调用命名sql_普元 EOS Platform 7.6 开发命名SQL缓存示例
  12. 计算机桌面设置上时间表,桌面时钟怎么设置-电脑显示时间不对 怎么校准电脑右下角显示的时间?...
  13. UserScript(用户脚本)在Firefox、Google Chrome、Opera、IE6-9等不同浏览器上的使用
  14. 生活中的逻辑谬误07.中间立场假两难推理
  15. Udacity DNN
  16. 02_基于西门子CM1241的ModbusRTU串口通讯实现
  17. 小程序uni-app介绍
  18. 计算机基础知识与Java语言概述(DAY1)
  19. Hadoop第四天--shell编程
  20. OpenEmbedded Yocto BitBake Poky以及之间关系

热门文章

  1. ios keychain 不被清理_清理iPhone内存【超实用】
  2. 你了解机械键盘吗?Keychron Q1开箱与体验实录
  3. [转]PHP程序段错误分析
  4. html5网易云歌词滚动,30行代码爬取网易云歌词(示例代码)
  5. OSChina 周三乱弹 —— 我们无法成为野兽
  6. 计算机图形技术与CAD,《计算机图形学与CAD技术》考试参考资料.docx
  7. mysql设置索引长度_修改Mysql索引长度限制
  8. 给Android工程师的音视频开发学习指南
  9. xbrl 数据比较分析_思考XML,使用XBRL分析财务报告
  10. HDFS核心进阶-namenode进阶