1. 程式人生 > >c++ curl下載和上傳資料——c++(學習一)

c++ curl下載和上傳資料——c++(學習一)

首先必須感謝稀泥蟹大神的這篇文章。還有官網讓我學習和使用了curl這個庫。具體的curl的詳解,請前往那裡觀看。我這裡就是用c++封裝了一下。還有說明一下,我這個是用在我的cocos2dx遊戲裡的。所以如果單獨拿出來有問題的話還望指出,OK,直接上乾貨吧!隨便提一下,使用它的時候應該開個執行緒。不然會一直阻塞在那裡!!

//.hpp
#ifndef FCFTestNetWorkManager_hpp
#define FCFTestNetWorkManager_hpp

#include <stdio.h>
#include "curl.h"
#include <string.h>
using namespace std; typedef std::function<void (string & response)>SuccessFinishedCallBack;//請求成功,有資料返回 class FCFTestNetWorkManager{ public: //使用單例 static FCFTestNetWorkManager* getInstance(); //使用get方法 int GetHttpRequest(const string & strUrl,SuccessFinishedCallBack callback); //使用post方法
int PostHttpRequest(const string & strUrl,const string & filePath,map<string,string>params,SuccessFinishedCallBack callback); public: //設定回撥 void setSuccesseCallBack(SuccessFinishedCallBack callBack); //設定m_debug void setDebug(bool debug); //返回的資料處理 static size_t write_data(void
* buffer,size_t size, size_t nmenb,void * lpvoid); //debug static int onDebug(CURL * curl,curl_infotype itype,char * pData,size_t size,void * lpvoid); //進度 static int updateProgress(void* ptr,double rDlTotal,double rDlNow,double rUlTotal,double rUlNow); private: static FCFTestNetWorkManager * __instance; FCFTestNetWorkManager(); ~FCFTestNetWorkManager(); bool m_debug; SuccessFinishedCallBack SuccessCallBack; }; #endif /* FCFTestNetWorkManager_hpp */
.cpp
#include "FCFTestNetWorkManager.hpp"

FCFTestNetWorkManager* FCFTestNetWorkManager::__instance = NULL;
FCFTestNetWorkManager* FCFTestNetWorkManager::getInstance()
{
    if (NULL == __instance) {
        __instance = new FCFTestNetWorkManager();
    }
    return __instance;
}

FCFTestNetWorkManager::FCFTestNetWorkManager():m_debug(false),SuccessCallBack(nullptr)
{

}

FCFTestNetWorkManager::~FCFTestNetWorkManager()
{

}

void FCFTestNetWorkManager::setSuccesseCallBack(SuccessFinishedCallBack callBack)
{
    SuccessCallBack = callBack;
}

void FCFTestNetWorkManager::setDebug(bool debug)
{
    m_debug = debug;
}

int FCFTestNetWorkManager::onDebug(CURL * curl,curl_infotype itype,char * pData,size_t size,void * lpvoid)
{
    if (itype == CURLINFO_TEXT) {
        printf("[text] %s\n",pData);
    }else if(itype == CURLINFO_HEADER_IN){
        printf("[HEADER_IN] %s\n",pData);
    }else if(itype == CURLINFO_HEADER_OUT){
        printf("[HEADER_IN] %s\n",pData);
    }else if(itype == CURLINFO_DATA_IN){
        printf("[HEADER_IN] %s\n",pData);
    }else if(itype == CURLINFO_DATA_OUT){
        printf("[HEADER_IN] %s\n",pData);
    }
    return (int)itype;
}

size_t FCFTestNetWorkManager::write_data(void * buffer,size_t size, size_t nmenb,void * lpvoid)
{
    string * str = dynamic_cast<string *>((string*)lpvoid);
    if (NULL == str || NULL == buffer) {
        return -1;
    }
    char * pData = (char *)buffer;
    str->append(pData,size*nmenb);
    return nmenb;
}

int FCFTestNetWorkManager::updateProgress(void* ptr,double rDlTotal,double rDlNow,double rUlTotal,double rUlNow)
{
    CCLOG("進度%f",rUlNow);
    return 0;
}

//get請求
int FCFTestNetWorkManager::GetHttpRequest(const string & strUrl,SuccessFinishedCallBack callback)
{
    string strResponse;//返回資料
    CURL * curl;
    CURLcode res;

    curl_global_init(CURL_GLOBAL_DEFAULT);//

    curl = curl_easy_init();//初始化控制代碼

    if (NULL == curl) {
        return CURLE_FAILED_INIT;
    }
    if(m_debug){
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);//這個CURLOPT_VERBOSE設為1,將顯示出所有傳送的實體協議的細節
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, onDebug);//這裡將呼叫onDebug除錯所有資訊
    }
    curl_easy_setopt(curl,CURLOPT_URL,strUrl.c_str());//設定url
    curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_data);//呼叫處理函式
    curl_easy_setopt(curl,CURLOPT_WRITEDATA, (void *)&strResponse);//返回的資料,這裡可以加個函式指標
    curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT, 3);//設定連結時長
    res = curl_easy_perform(curl);//開始下載
    if (res == CURLE_OK) {
        callback(strResponse);
    }
    curl_global_cleanup();
    curl_easy_cleanup(curl);//
    return res;
}

//post請求
int  FCFTestNetWorkManager::PostHttpRequest(const string & strUrl,const string & filePath,map<string,string>params,SuccessFinishedCallBack callback)
{
    string strResponse;//返回資料
    int progress;
    CURL * curl;
    CURLcode res;

    struct curl_httppost * post = NULL;
    struct curl_httppost * last = NULL;
    struct curl_slist * headers = NULL;
    static const char buf[] = "Expect:";
    //配置上傳檔案的表單
    if (!filePath.empty()) {
        curl_formadd(&post,&last,
                     CURLFORM_COPYNAME,"pic",
                     CURLFORM_FILE,filePath.c_str(),
                     CURLFORM_CONTENTTYPE,"image/jpeg",
                     CURLFORM_END);
    }
    //配置引數
    for (auto iter = params.begin(); iter != params.end(); iter++) {
        curl_formadd(&post, &last,
                     CURLFORM_COPYNAME,iter->first.c_str(),
                     CURLFORM_COPYCONTENTS,iter->second.c_str(),
                     CURLFORM_END);
    }
    //
    curl = curl_easy_init();//初始化控制代碼

    if (NULL == curl) {
        return CURLE_FAILED_INIT;
    }
    if(m_debug){
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);//這個CURLOPT_VERBOSE設為1,將顯示出所有傳送的實體協議的細節
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, onDebug);//這裡將呼叫onDebug除錯所有資訊
    }
    headers = curl_slist_append(headers, buf);//
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    curl_easy_setopt(curl, CURLOPT_HTTPPOST,post);//表單
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&strResponse);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,write_data);
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS,false);//是否需要進度
    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, updateProgress);//進度函式
    curl_easy_setopt(curl, CURLOPT_PROGRESSDATA,progress);//進度資料
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT,5);//連線時間
    res = curl_easy_perform(curl);
    if (res == CURLE_OK) {
        callback(strResponse);
    }
    curl_global_cleanup();
    curl_easy_cleanup(curl);
    curl_formfree(post);
    curl_slist_free_all(headers);
    return res;
}
//使用get
FCFTestNetWorkManager::getInstance()->GetHttpRequest(requestUrl, [](string & response){
        log("%s",response.c_str());
});
//使用post
FCFTestNetWorkManager::getInstance()->PostHttpRequest(requestUrl, getImgPath(), params, [](string & response){
        log("%s",response.c_str());
});