Windows下的LibCurl封装类
资源来自于网络,此处备份:
#ifndef CLIBCURL_H #define CLIBCURL_H /***************************************** *封装Libcurl下载库 *author:Jelin *date:2016年2月24日 */ #include <curl/curl.h> #include <string> using std::string; class CLibcurlCallback { public: virtual void Progress(void* lpParam, double dTotal, double bLoaded) = 0; }; enum LibcurlFlag { Lf_None = 0, Lf_Download, Lf_Post, Lf_Get, }; class CLibcurl { public: CLibcurl(void); ~CLibcurl(void); /****************************************************************************** *封装类的外部调用接口 */ bool SetPort(LONG port); //设置连接端口号 bool SetTimeout(int nSecond); //设置执行超时(秒) bool SetConnectTimeout(int nSecond); //设置连接超时(秒) bool SetUserAgent(LPCSTR lpAgent); //设置用户代理 bool SetResumeFrom(LONG lPos); //设置断点续传起始位置 bool SetResumeFromLarge(LONGLONG llPos); //设置断点续传起始位置,针对大文件 bool AddHeader(LPCSTR lpKey, LPCSTR lpValue); //添加自定义头 void ClearHeaderList(); //清理HTTP列表头 bool SetCookie(LPCSTR lpCookie); //设置HTTP请求cookie bool SetCookieFile(LPCSTR lpFilePath); //设置HTTP请求cookie文件 const char* GetError()const; //获取错误详细信息 void SetCallback(CLibcurlCallback* pCallback, void* lpParam); //设置下载进度回调 bool DownloadToFile(LPCSTR lpUrl, LPCSTR lpFile); //下载文件到磁盘 bool Post(LPCSTR lpUrl, LPCSTR lpData); //Post 字符串数据 bool Post(LPCSTR lpUrl, unsigned char* lpData, unsigned int nSize); //Post 字符串或者二进制数据 bool Get(LPCSTR lpUrl); //Get 请求 const string& GetRespons()const; //获取Post/Get请求返回数据 const char* GetResponsPtr()const; //获取Post/Get请求返回数据 protected: static size_t WriteCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam); static size_t HeaderCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam); static int ProgressCallback(void *pParam, double dltotal, double dlnow, double ultotal, double ulnow); private: CURL *m_pCurl; LONG m_nPort; HANDLE m_hFile; CURLcode m_curlCode; string m_strRespons; LibcurlFlag m_lfFlag; curl_slist *m_curlList; void *m_pCallbackParam; CLibcurlCallback *m_pCallback; }; #endif // CLIBCURL_H
实现文件:
#include "StdAfx.h" #include "Libcurl.h" #include <assert.h> #ifdef _DEBUG #pragma comment(lib, "libcurl/libcurld_SSL") #pragma comment(lib, "libcurl/libeay32.lib") #pragma comment(lib, "libcurl/ssleay32.lib") #else #pragma comment(lib, "libcurl//libcurl") #endif #pragma comment(lib, "ws2_32") #pragma comment(lib, "Iphlpapi") #pragma comment(lib, "Wldap32") CLibcurl::CLibcurl(void) : m_pCurl(NULL) , m_nPort(80) , m_hFile(INVALID_HANDLE_VALUE) , m_pCallback(NULL) , m_pCallbackParam(NULL) , m_curlCode(CURLE_OK) , m_lfFlag(Lf_None) , m_curlList(NULL) { m_pCurl = curl_easy_init(); curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, this); } CLibcurl::~CLibcurl(void) { ClearHeaderList(); curl_easy_cleanup(m_pCurl); if ( m_hFile != INVALID_HANDLE_VALUE ) { CloseHandle(m_hFile); } } bool CLibcurl::SetPort( LONG port ) { if ( port == m_nPort ) return true; m_nPort = port; m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_PORT, m_nPort); return CURLE_OK == m_curlCode; } bool CLibcurl::SetTimeout( int nSecond ) { if ( nSecond<0 ) return false; m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT, nSecond); return CURLE_OK == m_curlCode; } bool CLibcurl::SetConnectTimeout( int nSecond ) { if ( nSecond<0 ) return false; m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_CONNECTTIMEOUT, nSecond); return CURLE_OK == m_curlCode; } bool CLibcurl::SetUserAgent( LPCSTR lpAgent ) { if ( NULL == lpAgent ) return false; int nLen = strlen(lpAgent); if ( nLen == 0 ) return false; m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_USERAGENT, lpAgent); return CURLE_OK == m_curlCode; } bool CLibcurl::SetResumeFrom( LONG lPos ) { if ( lPos<0 ) return false; m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_RESUME_FROM, lPos); return CURLE_OK == m_curlCode; } bool CLibcurl::SetResumeFromLarge( LONGLONG llPos ) { if ( llPos<0 ) return false; m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_RESUME_FROM_LARGE, llPos); return CURLE_OK == m_curlCode; } bool CLibcurl::AddHeader( LPCSTR lpKey, LPCSTR lpValue ) { assert(lpKey!=NULL && lpValue!=NULL); int nLen1 = strlen(lpKey), nLen2 = strlen(lpValue); assert(nLen1>0 && nLen2>0); string strHeader(lpKey); strHeader.append(": "); strHeader.append(lpValue); m_curlList = curl_slist_append(m_curlList, strHeader.c_str()); m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, m_curlList); return CURLE_OK == m_curlCode; } void CLibcurl::ClearHeaderList() { if ( m_curlList ) { curl_slist_free_all(m_curlList); m_curlList = NULL; } } bool CLibcurl::SetCookie( LPCSTR lpCookie ) { assert(lpCookie!=NULL); m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_COOKIE, lpCookie); return CURLE_OK == m_curlCode; } bool CLibcurl::SetCookieFile( LPCSTR lpFilePath ) { assert(lpFilePath!=NULL); m_curlCode = curl_easy_setopt(m_pCurl, CURLOPT_COOKIEFILE, lpFilePath); return CURLE_OK == m_curlCode; } const char* CLibcurl::GetError() const { return curl_easy_strerror(m_curlCode); } void CLibcurl::SetCallback( CLibcurlCallback* pCallback, void* lpParam ) { m_pCallbackParam = lpParam; m_pCallback = pCallback; } bool CLibcurl::DownloadToFile( LPCSTR lpUrl, LPCSTR lpFile ) { CURLcode code = curl_easy_setopt(m_pCurl, CURLOPT_URL, lpUrl); DeleteFileA(lpFile); m_hFile = CreateFileA(lpFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if ( INVALID_HANDLE_VALUE == m_hFile ) { return FALSE; } curl_easy_setopt(m_pCurl, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSFUNCTION, ProgressCallback); curl_easy_setopt(m_pCurl, CURLOPT_PROGRESSDATA, this); m_lfFlag = Lf_Download; //开始执行请求 m_curlCode = curl_easy_perform(m_pCurl); return CURLE_OK == m_curlCode; } bool CLibcurl::Post( LPCSTR lpUrl, LPCSTR lpData ) { assert(lpData!=NULL); curl_easy_setopt(m_pCurl, CURLOPT_POST, 1); curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, lpData); //curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, lpData); curl_easy_setopt(m_pCurl, CURLOPT_URL, lpUrl); m_lfFlag = Lf_Post; m_strRespons.clear(); m_curlCode = curl_easy_perform(m_pCurl); return CURLE_OK == m_curlCode; } bool CLibcurl::Post( LPCSTR lpUrl, unsigned char* lpData, unsigned int nSize ) { assert(lpData!=NULL && nSize>0); curl_easy_setopt(m_pCurl, CURLOPT_POST, 1); curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, lpData); curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDSIZE, nSize); curl_easy_setopt(m_pCurl, CURLOPT_URL, lpUrl); m_lfFlag = Lf_Post; m_strRespons.clear(); m_curlCode = curl_easy_perform(m_pCurl); return CURLE_OK == m_curlCode; } bool CLibcurl::Get( LPCSTR lpUrl ) { assert(lpUrl!=NULL); curl_easy_setopt(m_pCurl, CURLOPT_HTTPGET, 1); curl_easy_setopt(m_pCurl, CURLOPT_URL, lpUrl); curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1);//支持重定向 curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, 0L); m_lfFlag = Lf_Get; m_strRespons.clear(); m_curlCode = curl_easy_perform(m_pCurl); return CURLE_OK == m_curlCode; } const string& CLibcurl::GetRespons() const { return m_strRespons; } const char* CLibcurl::GetResponsPtr() const { return m_strRespons.c_str(); } size_t CLibcurl::WriteCallback( void* pBuffer, size_t nSize, size_t nMemByte, void* pParam ) { //把下载到的数据以追加的方式写入文件(一定要有a,否则前面写入的内容就会被覆盖了) CLibcurl* pThis = (CLibcurl*)pParam; DWORD dwWritten = 0; switch( pThis->m_lfFlag ) { case Lf_Download://下载 { if ( pThis->m_hFile == INVALID_HANDLE_VALUE ) return 0; if ( !WriteFile(pThis->m_hFile, pBuffer, nSize*nMemByte, &dwWritten, NULL) ) return 0; } break; case Lf_Post://Post数据 case Lf_Get://Get数据 { pThis->m_strRespons.append((const char*)pBuffer, nSize*nMemByte); dwWritten = nSize*nMemByte; } break; case Lf_None://未定义 break; } return dwWritten; } size_t CLibcurl::HeaderCallback( void* pBuffer, size_t nSize, size_t nMemByte, void* pParam ) { CLibcurl* pThis = (CLibcurl*)pParam; return 0; } int CLibcurl::ProgressCallback( void *pParam, double dltotal, double dlnow, double ultotal, double ulnow ) { CLibcurl* pThis = (CLibcurl*)pParam; if ( pThis->m_pCallback ) { pThis->m_pCallback->Progress(pThis->m_pCallbackParam, dltotal, dlnow); } return 0; }
备份!