coco2dx c++ HTTP实现
coco2dx c++ HTTP實(shí)現(xiàn)?
達(dá)到的結(jié)果如下面的
iPhone截圖
android 日志截圖
流程圖例如以下
功能主要通過(guò)CURL c pthread 實(shí)現(xiàn) 我實(shí)現(xiàn)的不是多線程斷點(diǎn)(假設(shè)要實(shí)現(xiàn)能夠依據(jù)我這個(gè)進(jìn)行加入任務(wù)序列,可參考 cocos2d-x 中AssetsManager的實(shí)現(xiàn),事實(shí)上我的部分也是參考這個(gè)寫的 為什么寫這個(gè)呢 原因就是 AssetsManager是不支持?jǐn)帱c(diǎn)續(xù)傳的)
博客地址:http://blog.csdn.net/vpingchangxin/article/details/22309067
詳細(xì)能夠去CURL官網(wǎng)或者找資料科普一下
PS:假設(shè)是版本號(hào)公布最后設(shè)置超時(shí)時(shí)間20秒左右否則下載會(huì)占用很多其它下載實(shí)現(xiàn)效率等問題 我是為了測(cè)試 設(shè)置超時(shí)時(shí)間為2秒
1.先創(chuàng)建一個(gè)界面進(jìn)行控制進(jìn)行下載、停止、刪除、進(jìn)度 并綁定事件
2.在進(jìn)行下載中開一個(gè)線程進(jìn)行下載 (由于牽涉到UI,不開線程UI會(huì)卡著阻塞UI線程直到下載完畢)以下是事件中的控制 HelloWorldSecene.cpp中的實(shí)現(xiàn)
void HelloWorld::menuCallback(CCObject* pSender) {CCMenuItem *item = (CCMenuItem *)pSender;switch (item->getTag()) {case 1: // down startCCDirector::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(HelloWorld::updateUI), this, 0, false); // HttpClient中參考isStop = false;this->threadStart();break;case 2: // down stopisStop = true;break;case 3:if (isStop) {CCLog("downFilePath:%s",downFilePath.c_str());if (access(downFilePath.c_str(), 0) == 0) {remove(downFilePath.c_str());CCMessageBox("刪除成功", "溫馨提示");}else{CCMessageBox("沒有找到文件文件夾", "溫馨提示");}}else{CCMessageBox("下載中或沒有文件下載", "溫馨提示");}break;default:break;} }3。
實(shí)現(xiàn)線程類并回調(diào)設(shè)置
// 啟動(dòng)線程的方法 int HelloWorld::threadStart() {pthread_mutex_init(&g_downloadMutex, NULL);int errCode=0;pthread_t th_curlDown; // 線程初始化do {pthread_attr_t tAttr;errCode=pthread_attr_init(&tAttr);CC_BREAK_IF(errCode!=0);errCode=pthread_attr_setdetachstate(&tAttr, PTHREAD_CREATE_DETACHED);if(errCode!=0) {pthread_attr_destroy(&tAttr);break;}errCode=pthread_create(&th_curlDown, &tAttr, thread_funcation, this);} while (0);return errCode; }// 須要線程來(lái)完畢的功能都寫在這個(gè)函數(shù)里 void* HelloWorld::thread_funcation(void *arg) {CCLOG("thread started...");HelloWorld *hw = (HelloWorld*)arg;hw->ccc = new CurlDown("http://developer.baidu.com/map/static/doc/output/BaiduMap_AndroidSDK_v2.4.0_All.zip",hw->downFilePath);// ccc->mDownloadUrl = "http://developer.baidu.com/map/static/doc/output/BaiduMap_AndroidSDK_v2.4.0_All.zip";// int leng = ccc->getDownloadFileLenth();hw->ccc->setDelegate(hw);hw->ccc->downloadControler();return NULL; }4.實(shí)現(xiàn)回調(diào)進(jìn)度、成功、錯(cuò)誤(里面用到線程鎖對(duì)數(shù)據(jù)進(jìn)度更新UI,本來(lái)對(duì)線程就不熟悉,問了群里面的大牛,看了不少資料)
void HelloWorld::onError(CurlDown::ErrorCode errorCode){CCLog("error");pthread_mutex_lock(&g_downloadMutex);updateStr = "error";pthread_mutex_unlock(&g_downloadMutex);CCDirector::sharedDirector()->getScheduler()->unscheduleSelector(schedule_selector(HelloWorld::updateUI), this); } void HelloWorld::onProgress(double percent, void *delegate, string filefullPath){ // 下載進(jìn)度CCLog("donw progress:%.2f%%",percent);if (isStop) {CurlDown * cd = (CurlDown *)delegate;// pthread_mutex_lock(&g_downloadMutex);cd->setStopDown();// pthread_mutex_unlock(&g_downloadMutex);}pthread_mutex_lock(&g_downloadMutex);const char * per =CCString::createWithFormat("donw progress:%.2f%%",percent)->getCString();updateStr = per;downFilePath = filefullPath;pthread_mutex_unlock(&g_downloadMutex); } void HelloWorld::onSuccess(string filefullPath){CCLog("success");pthread_mutex_lock(&g_downloadMutex);updateStr = "success";downFilePath = filefullPath;pthread_mutex_unlock(&g_downloadMutex); }
5.CurlDown.h?CurlDown.cpp類實(shí)現(xiàn)?(能夠直接抽取出來(lái)用于不論什么地方。沒有牽涉到cocos2d-x部分,cocos2d-x?部分能夠刪除沒關(guān)系)
1)對(duì)類初始化
static pthread_mutex_t g_downloadMutex_1;CurlDown::~CurlDown(){mFileLenth = 0; } CurlDown::CurlDown():isStop(false),mDownloadUrl(""),timeout(2){ // test timeout 2 seconds. if release timeout 20 secondsmFileLenth = 0;mFilePath = "";pthread_mutex_init(&g_downloadMutex_1, NULL); } CurlDown::CurlDown(string downUrl,string filePath):mFileLenth(0),isStop(false),mDownloadUrl(downUrl),timeout(2),mFilePath(filePath){ // test timeout 2 seconds. if release timeout 20 secondsmDownloadUrl = downUrl;pthread_mutex_init(&g_downloadMutex_1, NULL); }void CurlDown::setDelegate(CurlDownDelegate * delegate) {mDelegate = delegate; }
2)控制下載方法
void CurlDown::downloadControler() {CCLog("--1-");mFileLenth = getDownloadFileLenth(); // 獲取遠(yuǎn)程文件大小if (mFileLenth <= 0) {cout << "download file fail..." << endl;mDelegate->onError(kNetwork);return;}vector<string> searchPaths = CCFileUtils::sharedFileUtils()->getSearchPaths();vector<string>::iterator iter = searchPaths.begin();searchPaths.insert(iter, mFilePath);CCFileUtils::sharedFileUtils()->setSearchPaths(searchPaths);CCLog("--2-mFileLenth:%f",mFileLenth);mFileName = mDownloadUrl.substr(mDownloadUrl.rfind('/') + 1);CCLog("--3-");CCLog("mFileName:%s;",mFileName.c_str()); // mFilePath = CCFileUtils::sharedFileUtils()->getWritablePath(); // CCLog("--5-");mFilePath = mFilePath + mFileName;CCLog("mFilePath:%s",mFilePath.c_str());CCLog("--6-");bool ret = false;while (true){ // 循環(huán)下載 每30秒進(jìn)行下載 避免斷網(wǎng)情況ret = download(); //直接下載 進(jìn)行阻塞線程CCLog("----stop---%s------",isStop?"true":"false");if (isStop) { // 假設(shè)進(jìn)行停止 breakCCLog("----stop---------");break;}if (ret ){ //下載完畢break;}sleep(0.5); //每次下載中間間隔0.5秒}if (ret) {CCLog("download ok");mDelegate->onSuccess(mFilePath);} else {CCLog("download fail");mDelegate->onError(kUncompress);} }
3)核心下載
#pragma mark 進(jìn)行下載 bool CurlDown::download() {FILE *fp = NULL;if(access(mFilePath.c_str(), 0)==0) { // 以二進(jìn)制形式追加fp = fopen(mFilePath.c_str(), "ab+");} else { // 二進(jìn)制寫fp = fopen(mFilePath.c_str(), "wb");}if (fp == NULL) {// 假設(shè)文件初始化失敗進(jìn)行返回return false;}// 讀取本地文件下載大小long localFileLenth = getLocalFileLength(); //已經(jīng)下載的大小CCLog("filePath:%s。leng:%ld",mFilePath.c_str() , localFileLenth ); //4397779 //3377875CURL *handle = curl_easy_init();std::string packageUrl = mDownloadUrl; //下載地址+下載文件名稱curl_easy_setopt(handle, CURLOPT_URL, packageUrl.c_str()); // http://curl.haxx.se/libcurl/c/fopen.htmlcurl_easy_setopt(handle, CURLOPT_TIMEOUT, timeout);curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, my_write_func); //寫文件回調(diào)方法curl_easy_setopt(handle, CURLOPT_WRITEDATA, fp); // 寫入文件對(duì)象curl_easy_setopt(handle, CURLOPT_RESUME_FROM, localFileLenth); // 從本地大小位置進(jìn)行請(qǐng)求數(shù)據(jù)// curl_easy_setopt(handle, CURLOPT_RESUME_FROM_LARGE, localFileLenth); // 坑curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 0L);curl_easy_setopt(handle, CURLOPT_PROGRESSFUNCTION, my_progress_func ); //下載進(jìn)度回調(diào)方法curl_easy_setopt(handle, CURLOPT_PROGRESSDATA, this); // 傳入本類對(duì)象CURLcode res = curl_easy_perform(handle);fclose(fp);return res == CURLE_OK; }
以下大家要問道的就是求源代碼(^..^)源代碼已經(jīng)上傳github?https://github.com/pingchangxin/BPDownload?cesd 下載位置:http://download.csdn.net/detail/vpingchangxin/7108649
我就不再這里mac她跑到隔壁?windows在沒有運(yùn)行(至win繁瑣的頭痛的結(jié)構(gòu))
轉(zhuǎn)載于:https://www.cnblogs.com/hrhguanli/p/4573005.html
總結(jié)
以上是生活随笔為你收集整理的coco2dx c++ HTTP实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea快捷键汇总mac_Intelli
- 下一篇: VC内存泄露检查工具:Visual Le