首先必须感谢稀泥蟹大神的这篇文章。还有官网让我学习和使用了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());
});