博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
coco2dx c++ HTTP实现
阅读量:5127 次
发布时间:2019-06-13

本文共 7197 字,大约阅读时间需要 23 分钟。

coco2dx c++ HTTP实现 

达到的结果如下面的

iPhone截图

android 日志截图

流程图例如以下

功能主要通过CURL c pthread 实现 我实现的不是多线程断点(假设要实现能够依据我这个进行加入任务序列,可參考 cocos2d-x 中AssetsManager的实现,事实上我的部分也是參考这个写的 为什么写这个呢 原因就是 AssetsManager是不支持断点续传的)

博客地址:

详细能够去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
searchPaths = CCFileUtils::sharedFileUtils()->getSearchPaths(); vector
::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  cesd 下载位置:

我就不再这里mac她跑到隔壁 windows在没有运行(至win繁琐的头痛的结构)

转载于:https://www.cnblogs.com/hrhguanli/p/4573005.html

你可能感兴趣的文章
Java SE和Java EE应用的性能调优
查看>>
Android设计模式系列--原型模式
查看>>
免费的论文查重网站
查看>>
C语言程序第一次作业
查看>>
leetcode-Sort List
查看>>
中文词频统计
查看>>
了解node.js
查看>>
想做移动开发,先看看别人怎么做
查看>>
Eclipse相关集锦
查看>>
虚拟化架构中小型机构通用虚拟化架构
查看>>
继承条款effecitve c++ 条款41-45
查看>>
Java泛型的基本使用
查看>>
1076 Wifi密码 (15 分)
查看>>
noip模拟赛 党
查看>>
bzoj2038 [2009国家集训队]小Z的袜子(hose)
查看>>
Java反射机制及其Class类浅析
查看>>
Postman-----如何导入和导出
查看>>
移动设备显示尺寸大全 CSS3媒体查询
查看>>
图片等比例缩放及图片上下剧中
查看>>
【转载】Linux screen 命令详解
查看>>