c++ curl下載和上傳資料——c++(學習一)
阿新 • • 發佈:2019-02-14
首先必須感謝稀泥蟹大神的這篇文章。還有官網讓我學習和使用了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());
});