coco2dx c++ HTTP实现

达到的结果如下面的

iPhone截图

android 日志截图

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdnBpbmdjaGFuZ3hpbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

流程图例如以下

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdnBpbmdjaGFuZ3hpbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

功能主要通过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实现的更多相关文章

  1. 一个创建Coco2d-x项目的脚本

    1.使用环境 我测试的环境是Mac OS 10.10 +Coco2d-x 3.2,是使用shell写的脚本,应该linux/unix都应该 可以使用. 2.使用可能出现的问题 使用中可能会爆权限不足的 ...

  2. VS2012无法安装cocos2d-x-2.1.4 解决方法及VS2012新建coco2d-x项目(一)

    转自:http://www.cnblogs.com/wangpei/admin/EditPosts.aspx?opt=1 (注:此方法是可行,仅供参考,建议大家直接看我的 一见命令解决vs安装并创建c ...

  3. xcode 开发ios兼容性问题的上下黑边 和 coco2d-x 游戏分辨率适配 ResolutionPolicy::FIXED_WIDTH 都会引起上下黑边问题!!!

    1:Xcode6在iPhone5+iOS7模拟器上编译,上下有黑边问题 问题描述: Xcode6环境下,对iPhone5或iPhone5s模拟器,在iOS7或iOS7.1下运行,屏幕上下有黑边.在iO ...

  4. coco2d-x怎样创建project

    不知道coco2d-x从那个版本号開始用python创建project,一句话搞定,确实省去了好多麻烦. 首先定位到coco2d-x的文件夹到cocos2d-x-2.2.3\cocos2d-x-2.2 ...

  5. COCOS学习笔记--Cocod2dx内存管理(三)-Coco2d-x内存执行原理

    通过上两篇博客.我们对Cocos引用计数和Ref类.PoolManager类以及AutoreleasePool类已有所了解,那么接下来就通过举栗子来进一步看看Coco2d-x内存执行原理是如何的. / ...

  6. coco2dx实现翻拍效果

    昨天吃饭看见同事演示他做的翻牌效果,感觉不错,我心血来潮也来搞个,很简单直接上代码. class FlipCard : public CCNode { public: CREATE_FUNC(Flip ...

  7. coco2dx加载网络图片并保存

    直接上代码 bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !Layer::i ...

  8. Coco2dx 3D例子

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18     // add "HelloWorld" splash screen"   ...

  9. coco2dx服务器简单例子

    实现的单个socket例子,了解socket原理. 先创建一个win32的项目(命令行的),作为服务端 // SocketServer.cpp : 定义控制台应用程序的入口点.// #include ...

随机推荐

  1. 内网穿透神器ngrok(转)

    相信做Web开发的同学们,经常会遇到需要将本地部署的Web应用能够让公网环境直接访问到的情况,例如微信应用调试.支付宝接口调试等.这个时候,一个叫ngrok的神器可能会帮到你,它提供了一个能够在公网安 ...

  2. 页面提交错误,页面间参数传递java.lang.NumberFormatException: null

    多次出现这样的错误,在点击一个按钮触发提交整个页面的事件时,总是报错,不止一次出现这样的错误了. 出现这种问题的分析: 1 我们从这个问题的本身来看,java.lang.NumberFormatExc ...

  3. 仿ios版微信应用源代码

    仿微信基本功能. 基于XMPPserver的即时通信以及交友client. ----第一期代码的功能例如以下----      1.新用户注冊      2.登陆并连接XMPPserver 握手 保持 ...

  4. Qt 的内部进程通信机制

    Qt 的内部进程通信机制 续欣 (xxin76@hotmail.com), 博士.大学讲师 2004 年 4 月 01 日 Qt 作为一种跨平台的基于 C++ 的 GUI 系统,能够提供给用户构造图形 ...

  5. thinkPHP 输出及其模板调用(三)

    原文:thinkPHP 输出及其模板调用(三) ThinkPHP 的输出(重点) a.通过 echo 等PHP原生的输出方式在页面中输出 b.通过display方法输出(thinkphp\Home\L ...

  6. 【智能家居篇】wifi网络接入原理(上)——扫描Scanning

    转载请注明出处:http://blog.csdn.net/Righthek 谢谢! 对于低头党来说,在使用WIFI功能时,常常性的操作是打开手机上的WIFI设备,搜索到心目中的热点,输入passwor ...

  7. DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)

    DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类) 一.DAO模式简介 DAO即Data Access Object,数据访问接口.数据访问:故名思义就是与数据库打交道.夹在业务逻辑与数据 ...

  8. 公布一个软件,轻新视频录播程序,H264/AAC录制视音频,保存FLV,支持RTMP直播

    已经上传到CSDN,下载地址:http://download.csdn.net/detail/avsuper/7421647,不要钱滴,嘿嘿... 本程序能够把摄像头视频和麦克风音频,录制为FLV文件 ...

  9. 一二三(The Seventh Hunan Collegiate Programming Contest)

    一二三 你弟弟刚刚学会写英语的一(one).二(two)和三(three).他在纸上写了好些一二三,可惜有些字母写错了.已知每个单词最多有一个字母写错了(单词长度肯定不会错),你能认出他写的啥吗? 输 ...

  10. android 屏幕适配 课程笔记

    1 横竖屏切换:   文件名同样.  目录不同.   layout-port/ 代表竖屏   layout-land/ 代表横屏   layout/ 代表不论什么没有修饰符的layout目录.   终 ...