zoukankan      html  css  js  c++  java
  • curl 一个使用例子

    #include <iostream>
    #define Main main
    #include <string>
    #include <assert.h>
    #include <curl/curl.h>
    #include <curl/easy.h>
    
    #pragma comment(lib,"libcurl.lib")
    #pragma comment(lib,"ws2_32.lib")
    
    using namespace std;
    
    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 SetPorts(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;
    };
    class CLibcurlCallbackEx
        : public CLibcurlCallback
    {
    public:
        virtual void Progress(void* lpParam, double dTotal, double dLoaded)
        {
            if (dTotal == 0.0)
                return;
            double bPercent = (dLoaded / dTotal) * 100;
            printf("下载进度:%0.2lf%%
    ", bPercent);
        }
    
    };
    
    class CommonTools
    {
    public:
        CommonTools() {}
        ~CommonTools() {}
    public:
        static size_t receive_data(void *contents, size_t size, size_t nmemb, void *stream);
        // HTTP 下载文件的回掉函数
        static size_t writedata2file(void *ptr, size_t size, size_t nmemb, FILE *stream);
        // 文件下载接口
        static int download_file(const char* url, const char outfilename[FILENAME_MAX]);
        // http get 请求
        static CURLcode HttpGet(const std::string & strUrl, std::string & strResponse, int nTimeout);
        // htpp post 请求
        static CURLcode HttpPost(const std::string & strUrl, std::string szJson, std::string & strResponse, int nTimeout);
    };
    
    int Main()
    {
        //string url("http://t.weather.sojson.com/api/weather/city/101270101");
        //string buf;
        //CommonTools::HttpGet(url, buf, 300);
    
        //FILE *File = NULL;
        //fopen_s(&File, "test.json", "wb+");
        //if (File)
        //{
        //    fwrite(buf.c_str(), buf.length(), 1, File);
        //}
        //fclose(File);
        //File = NULL;
    
    
        system("pause");
        return 0;
    }
    
    
    
    
    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::SetPorts(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;
    }
    
    
    size_t CommonTools::receive_data(void *contents, size_t size, size_t nmemb, void *stream) {
        string *str = (string*)stream;
        (*str).append((char*)contents, size*nmemb);
        return size * nmemb;
    }
    
    size_t CommonTools::writedata2file(void *ptr, size_t size, size_t nmemb, FILE *stream) {
        size_t written = fwrite(ptr, size, nmemb, stream);
        return written;
    }
    
    int CommonTools::download_file(const char* url, const char outfilename[FILENAME_MAX]) {
        CURL *curl;
        FILE *fp;
        CURLcode res;
        /*   调用curl_global_init()初始化libcurl  */
        res = curl_global_init(CURL_GLOBAL_ALL);
        if (CURLE_OK != res)
        {
            printf("init libcurl failed.");
            curl_global_cleanup();
            return -1;
        }
        /*  调用curl_easy_init()函数得到 easy interface型指针  */
        curl = curl_easy_init();
        if (curl) {
            fp = fopen(outfilename, "wb");
    
            /*  调用curl_easy_setopt()设置传输选项 */
            res = curl_easy_setopt(curl, CURLOPT_URL, url);
            if (res != CURLE_OK)
            {
                fclose(fp);
                curl_easy_cleanup(curl);
                return -1;
            }
            /*  根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务  */
            res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CommonTools::writedata2file);
            if (res != CURLE_OK) {
                fclose(fp);
                curl_easy_cleanup(curl);
                return -1;
            }
            /*  根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务  */
            res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
            if (res != CURLE_OK)
            {
                fclose(fp);
                curl_easy_cleanup(curl);
                return -1;
            }
    
            res = curl_easy_perform(curl);
            // 调用curl_easy_perform()函数完成传输任务
            fclose(fp);
            /* Check for errors */
            if (res != CURLE_OK) {
                fprintf(stderr, "curl_easy_perform() failed: %s
    ", curl_easy_strerror(res));
                curl_easy_cleanup(curl);
                return -1;
            }
    
            /* always cleanup */
            curl_easy_cleanup(curl);
            // 调用curl_easy_cleanup()释放内存
    
        }
        curl_global_cleanup();
        return 0;
    }
    
    CURLcode CommonTools::HttpGet(const std::string & strUrl, std::string & strResponse, int nTimeout) {
        CURLcode res;
        CURL* pCURL = curl_easy_init();
    
        if (pCURL == NULL) {
            return CURLE_FAILED_INIT;
        }
    
        curl_easy_setopt(pCURL, CURLOPT_URL, strUrl.c_str());
        //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
        curl_easy_setopt(pCURL, CURLOPT_NOSIGNAL, 1L);
        curl_easy_setopt(pCURL, CURLOPT_TIMEOUT, nTimeout);
        curl_easy_setopt(pCURL, CURLOPT_NOPROGRESS, 1L);
        curl_easy_setopt(pCURL, CURLOPT_WRITEFUNCTION, CommonTools::receive_data);
        curl_easy_setopt(pCURL, CURLOPT_WRITEDATA, (void*)&strResponse);
        res = curl_easy_perform(pCURL);
        curl_easy_cleanup(pCURL);
        return res;
    }
    
    CURLcode CommonTools::HttpPost(const std::string & strUrl, std::string szJson, std::string & strResponse, int nTimeout) {
        CURLcode res;
        char szJsonData[1024];
        memset(szJsonData, 0, sizeof(szJsonData));
        strcpy(szJsonData, szJson.c_str());
        CURL* pCURL = curl_easy_init();
        struct curl_slist* headers = NULL;
        if (pCURL == NULL) {
            return CURLE_FAILED_INIT;
        }
    
        CURLcode ret;
        ret = curl_easy_setopt(pCURL, CURLOPT_URL, strUrl.c_str());
        //    std::cout << ret << std::endl;
    
        ret = curl_easy_setopt(pCURL, CURLOPT_POST, 1L);
        headers = curl_slist_append(headers, "content-type:application/json");
    
        ret = curl_easy_setopt(pCURL, CURLOPT_HTTPHEADER, headers);
    
        ret = curl_easy_setopt(pCURL, CURLOPT_POSTFIELDS, szJsonData);
        //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
        ret = curl_easy_setopt(pCURL, CURLOPT_TIMEOUT, nTimeout);
    
        ret = curl_easy_setopt(pCURL, CURLOPT_WRITEFUNCTION, CommonTools::receive_data);
    
        ret = curl_easy_setopt(pCURL, CURLOPT_WRITEDATA, (void*)&strResponse);
    
        res = curl_easy_perform(pCURL);
        curl_easy_cleanup(pCURL);
        return res;
    }
  • 相关阅读:
    【算法研究】目标检测
    【Java学习笔记】Java中方法和成员变量的访问控制
    DevExpress XtraReports 入门一 创建 Hello World 报表
    整理点dropdownList的应用
    Developer Express 之 XtraReport报表预览控件PrintControl设置
    C#实现winform仿div+css半透明遮罩效果
    动态传递参数到DevExpress.XtraReports的小结 .
    Developer Express 之 XtraReport如何显示设计窗体,打开已设计过的报表
    Developer Express 之 XtraReport如何动态绑定数据
    c#判断右键菜单(ContextMenuStrip)是从哪个控件弹出来的方法
  • 原文地址:https://www.cnblogs.com/YZFHKMS-X/p/11780627.html
Copyright © 2011-2022 走看看