coco2dx c++ HTTP实现

coco2dx c++ HTTP实现

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

全栈程序员社区此处内容已经被作者隐藏,请输入验证码查看内容
验证码:
请关注本站微信公众号,回复“验证码”,获取验证码。在微信里搜索“全栈程序员社区”或者“www_javaforall_cn”或者微信扫描右侧二维码都可以关注本站微信公众号。

coco2dx c++ HTTP实现 

达到的结果如下面的

iPhone截图coco2dx c++ HTTP实现

android 日志截图coco2dx c++ HTTP实现

流程图例如以下coco2dx c++ HTTP实现

功能主要通过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繁琐的头痛的结构)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117866.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 显示适配器virtual display device_电脑怎么设置虚拟显示器

    显示适配器virtual display device_电脑怎么设置虚拟显示器根据包括微软研究院在内的许多最新研究,多显示器系统以及更大的显示器可将用户工作效率提高10%至50%。然而,多显示器采用的增长以及大屏幕显示器受到以下几个因素的影响:虚拟显示管理器通过额外的虚拟显示器的便利性来补充您现有的单显示器或多显示器系统,这些虚拟显示器可以细分现有的物理屏幕,同时使用现有硬件以及单击按钮调用不同显示器配置的能力。VDM的虚拟显示技术提供了物理显示器的外观和感觉,并且需要对最终用户进行最少的重新培训。许可证区别虚拟显示管理器提供两个不同的许可证。CL–控制台许可证和MUL

    2022年8月21日
    159
  • 按位与、按位异或、按位取反「建议收藏」

    按位与、按位异或、按位取反「建议收藏」&按位与|按位或^按位异或1.按位与运算按位与运算符”&”是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1,否则为0。参与运算的数以补码方式出现。例如:9&5可写算式如下:00001001(9的二进制补码)&00000101(5的二进制补码)00000001(1的二进制补码)可见9&5=1。按位与运算通常用来对某些位

    2022年6月5日
    37
  • BMP文件解析_图片分析

    BMP文件解析_图片分析BMP文件简介BMP(全称Bitmap)是Window操作系统中的标准图像文件格式,可以分成两类:设备相关位图(DDB)和设备无关位图(DIB),使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。由于BMP文

    2025年6月16日
    3
  • ADB Shell 命令_手机adb命令大全

    ADB Shell 命令_手机adb命令大全文章目录查看前台Activity调用Activity查看正在运行的Services调用Service发送广播查看应用详细信息查看应用列表清除应用数据与缓存查看屏幕分辨率查看屏幕密度屏幕截图录制屏幕查看前台Activityadbshelldumpsysactivityactivities或者adbshelldumpsysactivitytop调用Activit…

    2022年10月18日
    2
  • 验证码的作用,为什么要存在验证码[通俗易懂]

    验证码的作用,为什么要存在验证码[通俗易懂]攻击者攻击客户端的一些手法:1、在WEB站有时会碰到客户机恶意攻击,其中一种很常见的攻击手段就是“身份欺骗”,它通过在客户机端脚本写入一些代码,然后利用它,客户机在网站、论坛反复登录2、攻击者创建

    2022年7月1日
    26
  • xshell 激活成功教程版安转教程

    xshell 激活成功教程版安转教程转自:https://www.cnblogs.com/bowendown/p/11937159.html,亲测perfect!目录一、xshell6商业版安装教程1.为什么要用xshell2

    2022年8月4日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号