coco2dx c++ HTTP實現

來源:互聯網
上載者:User

標籤:

coco2dx c++ HTTP實現 

達到的結果如下面的

iPhone

android 日誌

流程圖例如以下

功能主要通過CURL c pthread 實現 我實現的不是多線程斷點(假設要實現能夠依據我這個進行加入工作順序,可參考 cocos2d-x 中AssetsManager的實現,事實上我的部分也是參考這個寫的 為什麼寫這個呢 原因就是 AssetsManager是不支援斷點續傳的)

部落格地址:http://blog.csdn.net/vpingchangxin/article/details/22309067

詳細能夠去CURL官網或者找資料科普一下

PS:假設是版本號碼公布最後設定逾時時間20秒左右否則下載會佔用很多其它下載實現效率等問題 我是為了測試 設定逾時時間為2秒

1.先建立一個介面進行控制進行下載、停止、刪除、進度 並綁定事件

2.在進行下載中開一個線程進行下載 (由於牽涉到UI,不開線程UI會卡著阻塞UI線程直到下載完畢)以下是事件中的控制 HelloWorldSecene.cpp中的實現

void HelloWorld::menuCallback(CCObject* pSender) {    CCMenuItem *item = (CCMenuItem *)pSender;    switch (item->getTag()) {        case 1: // down start            CCDirector::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(HelloWorld::updateUI), this, 0, false); // HttpClient中參考            isStop = false;            this->threadStart();            break;        case 2: // down stop            isStop = 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。

實現線程類並回調設定

// 啟動線程的方法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;}// 須要線程來完畢的功能都寫在這個函數裡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.實現回調進度、成功、錯誤(裡面用到線程鎖對資料進度更新UI,本來對線程就不熟悉,問了群裡面的大牛,看了不少資料)

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){ // 下載進度    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類實現 (能夠直接抽取出來用於不論什麼地方。沒有牽涉到cocos2d-x部分,cocos2d-x 部分能夠刪除沒關係)

1)對類初始化

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 seconds    mFileLenth = 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 seconds    mDownloadUrl = downUrl;    pthread_mutex_init(&g_downloadMutex_1, NULL);}void CurlDown::setDelegate(CurlDownDelegate * delegate) {    mDelegate = delegate;}

2)控制下載方法

void CurlDown::downloadControler() {    CCLog("--1-");    mFileLenth = getDownloadFileLenth(); // 擷取遠程檔案大小    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){ // 迴圈下載 每30秒進行下載 避免斷網情況        ret = download(); //直接下載 進行阻塞線程        CCLog("----stop---%s------",isStop?"true":"false");        if (isStop) { // 假設進行停止 break            CCLog("----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 進行下載bool CurlDown::download() {    FILE *fp = NULL;    if(access(mFilePath.c_str(), 0)==0) { // 以二進位形式追加        fp = fopen(mFilePath.c_str(), "ab+");    } else { // 二進位寫        fp = fopen(mFilePath.c_str(), "wb");    }        if (fp == NULL) {// 假設檔案初始化失敗進行返回        return false;    }        // 讀取本地檔案下載大小    long localFileLenth = getLocalFileLength(); //已經下載的大小    CCLog("filePath:%s。leng:%ld",mFilePath.c_str() , localFileLenth ); //4397779 //3377875        CURL *handle = curl_easy_init();    std::string packageUrl = mDownloadUrl; //+下載檔案名稱    curl_easy_setopt(handle, CURLOPT_URL, packageUrl.c_str()); // http://curl.haxx.se/libcurl/c/fopen.html    curl_easy_setopt(handle, CURLOPT_TIMEOUT, timeout);    curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, my_write_func);   //寫檔案回調方法    curl_easy_setopt(handle, CURLOPT_WRITEDATA, fp); // 寫入檔案對象    curl_easy_setopt(handle, CURLOPT_RESUME_FROM, localFileLenth);  // 從本地大小位置進行請求資料    //    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 ); //下載進度回調方法    curl_easy_setopt(handle, CURLOPT_PROGRESSDATA, this); // 傳入本類對象        CURLcode res = curl_easy_perform(handle);    fclose(fp);    return res == CURLE_OK;}

以下大家要問道的就是求原始碼(^..^)原始碼已經上傳github https://github.com/pingchangxin/BPDownload cesd 下載位置:http://download.csdn.net/detail/vpingchangxin/7108649

我就不再這裡mac她跑到隔壁 windows在沒有運行(至win繁瑣的頭痛的結構)

coco2dx c++ HTTP實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.