微端启动器LAUNCHER的制作之MFC版二(下载)
用了C#再回来用C++写真的有一种我已经不属于这个世界的感觉。C++的下载就没有C#那么方便了,我用的是libcurl.dll,官网上下载的源码自己cmake出来编译的,c++的库引用有debug和release之分,所以刚开始写的时候用的是debug版,然后后来写完了之后改成了release版。
先上代码再来讲吧。
curl_global_init(CURL_GLOBAL_DEFAULT);
curl_global_cleanup();
这个是必须要有的全局初始化和清除,所以我把它放在了下载类的构造和析构里。
下载函数:
CURL * GetConfigCurlHandle = curl_easy_init(); //初始化一个curl,注意线程之间不能共享这个curl,多线程的话就每个线程自己设置一个curl
FtpFile ftpfile = { FileName.data(), NULL };
string strpath = Config::GetInstance()->m_sDownloadFile + "\\" + FileName;
fopen_s(&ftpfile.stream, strpath.data(), "ab+"); //一定要有+不然下一次写入就把之前的覆盖了
curl_easy_setopt(GetConfigCurlHandle, CURLOPT_URL, url.data()); //注册url
curl_easy_setopt(GetConfigCurlHandle, CURLOPT_WRITEFUNCTION, DownloadCallback); //注册一个回调函数用于写入文件
curl_easy_setopt(GetConfigCurlHandle, CURLOPT_WRITEDATA, &ftpfile);
curl_easy_setopt(GetConfigCurlHandle, CURLOPT_BUFFERSIZE, CURL_MAX_WRITE_SIZE); //设置缓冲区大小
ConfigRetcCode = curl_easy_perform(GetConfigCurlHandle);
if (ftpfile.stream)
{
string str = ftpfile.filename;
//Config::GetInstance()->WriteLog("关闭文件"+str);
fclose(ftpfile.stream);
}
if (ConfigRetcCode != CURLE_OK)
{
int co = ConfigRetcCode;
string str = FileName + "下载失败errorcode:"+Config::GetInstance()->FloatToString(co);
Config::GetInstance()->WriteLog(str);
if (ConfigRedownloadTime<10)
{
DownloadConfigFile(url, FileName);
}
ConfigRedownloadTime++;
}
else
{
return;
}
下载全部结束之后要清除这个curl:
curl_easy_cleanup(GetConfigCurlHandle);
有两个比较重要的坑了我的点,一个就是注册url的那里,我的url是string类型,直接传入string类型是不会报错的,但是这个下载会返回一个错误,错误码我不记得了大概就是找不到这个url的意思。而传入url.data()就没错了,也就是相当于把string转成了char*。其实C++中很多的函数都是不能识别string类型的参数的,在c++中传参还是少用string的好。至于原因哪个大牛能告诉我一下好想知道!!!写c#的时候只想怎么用,但是写c++就好想知道原理是怎么回事!
第二个点是我把打开文件和关闭文件的函数放在了回调函数中,但是如果是一个大文件的话他是没有办法一次就写完的,所以就会不断地去调用回调函数写入文件,也就会不断地打开和关闭,然后就出现了文件被占用导致写入失败的问题。这个我真的查了很久的原因,因为c++不像C#,C++的报错总是在很底层,我常说c++总是断在神奇的位置。于是我把下载线程屏蔽掉然后在主线程中循环的打开关闭这个文件夹,在打开和关闭中做一些耗时操作,结果并没有报错那说明文件并没有被其他线程占用,那么也就只可能是下载线程的问题。但是网上所有的关于这个libcurl下载大文件的问题都没有解释。后来有个大牛朋友跟我说了一个直写和后写的问题,他说文件写入磁盘分为直写和后写,直写就是调用写入函数的时候就写入磁盘,后写就是过一会再写入磁盘。我不知道具体的原因但是这个给了我启发,是不是文件写入磁盘的时候还没有写完而我就进行了下一次打开写入操作,虽然每一次打开文件之后我都关闭了文件,但是他仅仅只是对文件的操作成功了,而操作系统还在继续把文件写入磁盘中,所以导致下一次写入的时候报错的错误码是文件被占用。而我把打开和关闭操作放在了回调函数外也就是一个文件只进行一次打开和关闭就没有问题了。不知道自己的想法对不对希望有大牛能给我解释一下具体原因。跪谢~~~
还有一个点是我在C#中用http下载没有遇到过的就是下载失败的问题,下载失败原因很多,看错误码基本都是网络问题啊什么的,所有加入了一个循环递归,如果下载不成功就循环下载十次直到成功,如果十次还不成功那就只能告诉玩家你网不好待会再来吧。。。。。。这个在C#中没有遇到过可能是http自己封装了下载失败的处理程序吧。
微端启动器LAUNCHER的制作之MFC版二(下载)的更多相关文章
- 微端游戏启动器LAUNCHER的制作之MFC版一(序和进程通信)
额...刚开始信誓旦旦说要写launcher制作的博客,还没写完就被抛到脑后了真是没毅力.最近把之前写的wpf的launcher改成了mfc版,遇到很多问题,写了三个星期才写完,好好记录一下吧.我也想 ...
- 微端游戏启动器launcher的制作(序篇)
公司要做一个游戏接入腾讯QQ游戏大厅,腾讯要求制作一个launcher,公司之前并没有接入过腾讯,所以大家其实都不懂,而我又是新人,所以刚拿到这个任务的时候整个人就是一个大写的懵逼.在网上查找了不少的 ...
- 微端游戏启动器launcher的制作之下载篇(系列一)
首先第一篇先讲一讲launcher最核心的功能---下载功能. 这个部分估计得好几篇才能写完,东西比较多也比较杂,慢慢来吧,我的东西也在继续改进中...... 从web上下载文件需要用到几个类,Htt ...
- dotNet开发游戏微端
需求分析 功能要求 当玩家使用不支持 unity webplayer 的浏览器进入游戏时,让玩家通过微端玩游戏. 确保微端的功能和页游戏功能一致. 大体功能就是为unity web game开发微端, ...
- Egret微端 创建项目(一)
开发环境: window7 egret engine:5.0.14 egret wing:4.1.0 微端:v0.0.14 官方教程:http://developer.egret.com/cn/git ...
- 2D客户端+微端技术总结
本人于2013年9月23号加入一个页游项目组, 并作为项目组的客户端小组的主程, 带领一个4个人(峰值)的前端小组, 进行微端的开发.微端项目于2014年8月底大体完成, 历时11个月.9月份之后微端 ...
- 微端 代码project as air 分享
分享 ^_^ 1. 使用 air , as . 2. 微端下载和更新技术 成功上线棋牌游戏.它可用于传统的游戏开发. 地址: http://download.csdn.net/detail/stone ...
- Unity下的开发框架--适应web和微端游戏异步资源请求的框架
一. 内容简介: 1. 框架对Web与微端游戏特性的支持: Web和微端游戏最重要的特性是,资源是持续从服务器上即时下载下来的.而保证体验流畅的关键就是保证资源下载分散到持续的体验过程中,并保 ...
- 微端 打包更新工具 as air 分享
分享 微端,更新的是散包,不像端游,一个大包搞定. 更新须要每次用工具把资源的散文件.依据文件夹结构及时间 生成一个列表, 每次更新就是 文件夹及时间的比对! 该project能够翻译成 其它语言.有 ...
随机推荐
- hibernate---性能优化, 1+N问题
session级缓存 保存一个hashmap, 读出来的对象放在里面, 如果读出来50条放50条, 如果另起session原来的50条就被清除.可以手动session.clear清除. 如果同一个se ...
- Arduino单片机使用和开发问题记录(转)
源:Arduino单片机使用和开发问题记录 1.将程序上传到板子时Arduino IDE提示“avrdude: stk500_getsync(): not in sync: resp=0x00” 网上 ...
- C# GridView Edit & Delete, 点击Delete的时候弹出确认框
1. 使用GridView自带属性ShowEditButton和ShowDeleteButton,均设为True <Columns> ... <asp:CommandField S ...
- mongodb 导入数据库文件
吐槽一下: 这个导入现有数据文件弱爆了... 直接将要导入的数据文件放到mongodb下的db目录下就完事了...O(∩_∩)O哈哈~ 例如: 将shop_suning (shopdb_suning ...
- UVa 341 - Non-Stop Travel
题目大意:给一个地区的地图,上面有若干路口,每个路口因为红灯的缘故要耽误一些时间,给出起点和终点,找出最短路径使得耽误时间最短. 单源最短路问题,Dijkstra算法.同时还要打印路径. #inclu ...
- DNS分析
一.DNS服务器 区域传送: 区域(zone)和 域(domain) 区域:物理概念 域:逻辑概念 区域数据库文件: 资源记录:RR 有类型:A AAAA PTR SOA NS CNAME MX SO ...
- UVa 10716 - Evil Straw Warts Live
题目大意:给一个字符串,判断是否能通过交换字母构成回文,如果能,计算所需的最小交换次数. 如果字符串中出现奇数次的字母的个数>1,则不能构成回文.然后...就没思路了...看网上说用贪心的思想先 ...
- python 自动化之路 day 13
本节内容参考博客: http://www.cnblogs.com/wupeiqi/articles/5132791.html http://www.cnblogs.com/wupeiqi/articl ...
- Angular - - ngChange、ngChecked、ngClick、ngDblclick
ngChange 当用户更改输入时,执行给定的表达式.表达式是立即进行执行的,这个和javascript的onChange事件的只有在触发事件的变化结束的时候执行不同. 格式:ng-change=”v ...
- iOS 之 绘图简介
iOS 实现图形编程主要有三种技术:UIKit.Core Graphics.OpenGL. 绘图需要在图形环境中进行,图形环境分为三种:屏幕图形环境.off screen 位图环境和PDF图形环境.在 ...