用了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版二(下载)的更多相关文章

  1. 微端游戏启动器LAUNCHER的制作之MFC版一(序和进程通信)

    额...刚开始信誓旦旦说要写launcher制作的博客,还没写完就被抛到脑后了真是没毅力.最近把之前写的wpf的launcher改成了mfc版,遇到很多问题,写了三个星期才写完,好好记录一下吧.我也想 ...

  2. 微端游戏启动器launcher的制作(序篇)

    公司要做一个游戏接入腾讯QQ游戏大厅,腾讯要求制作一个launcher,公司之前并没有接入过腾讯,所以大家其实都不懂,而我又是新人,所以刚拿到这个任务的时候整个人就是一个大写的懵逼.在网上查找了不少的 ...

  3. 微端游戏启动器launcher的制作之下载篇(系列一)

    首先第一篇先讲一讲launcher最核心的功能---下载功能. 这个部分估计得好几篇才能写完,东西比较多也比较杂,慢慢来吧,我的东西也在继续改进中...... 从web上下载文件需要用到几个类,Htt ...

  4. dotNet开发游戏微端

    需求分析 功能要求 当玩家使用不支持 unity webplayer 的浏览器进入游戏时,让玩家通过微端玩游戏. 确保微端的功能和页游戏功能一致. 大体功能就是为unity web game开发微端, ...

  5. Egret微端 创建项目(一)

    开发环境: window7 egret engine:5.0.14 egret wing:4.1.0 微端:v0.0.14 官方教程:http://developer.egret.com/cn/git ...

  6. 2D客户端+微端技术总结

    本人于2013年9月23号加入一个页游项目组, 并作为项目组的客户端小组的主程, 带领一个4个人(峰值)的前端小组, 进行微端的开发.微端项目于2014年8月底大体完成, 历时11个月.9月份之后微端 ...

  7. 微端 代码project as air 分享

    分享 ^_^ 1. 使用 air , as . 2. 微端下载和更新技术 成功上线棋牌游戏.它可用于传统的游戏开发. 地址: http://download.csdn.net/detail/stone ...

  8. Unity下的开发框架--适应web和微端游戏异步资源请求的框架

    一.   内容简介: 1.   框架对Web与微端游戏特性的支持: Web和微端游戏最重要的特性是,资源是持续从服务器上即时下载下来的.而保证体验流畅的关键就是保证资源下载分散到持续的体验过程中,并保 ...

  9. 微端 打包更新工具 as air 分享

    分享 微端,更新的是散包,不像端游,一个大包搞定. 更新须要每次用工具把资源的散文件.依据文件夹结构及时间 生成一个列表, 每次更新就是 文件夹及时间的比对! 该project能够翻译成 其它语言.有 ...

随机推荐

  1. [iOS] 响应式编程开发-ReactiveCocoa(一)

    什么是响应式编程 响应式编程是一种面向数据流和变化传播的编程范式.这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播. 例如,在命令式编程环境中 ...

  2. CDOJ 1268 Open the lightings

    组合数学题.好难啊,请教了Xiang578大神&&看了他题解才会的...... 甩上题解链接:http://blog.csdn.net/xinag578/article/details ...

  3. 在阿里云ECS(CentOS6.5)上安装redis

    下载所需的redis 命令: wget http://download.redis.io/releases/redis-3.0.7.tar.gz 结果: 解压redis压缩文件: 命令: .tar.g ...

  4. [转]解决Maven报错"Plugin execution not covered by lifecycle configuration"

    [转]解决Maven报错"Plugin execution not covered by lifecycle configuration" 导入Myabtis源码后,POM文件会报 ...

  5. Android L(5.0)源码之开放的图形库接口——OpenGL ES

    最近在研究android 5.0的gallery模块,学习了相关的知识点,准备写点博客总结一下,有时间了会补充完整

  6. Android.mk文件详解(转)

    源:Android.mk文件详解 从对Makefile一无所知开始,折腾了一个多星期,终于对Android.mk有了一个全面些的了解.了解了标准的Makefile后,发现Android.mk其实是把真 ...

  7. TLD视觉跟踪算法(转)

    源:TLD视觉跟踪算法 TLD算法好牛逼一个,这里有个视频,是作者展示算法的效果,http://www.56.com/u83/v_NTk3Mzc1NTI.html.下面这个csdn博客里有人做的相关总 ...

  8. java 正则匹配int型

    private static Pattern DIGIT_PATTERN = Pattern.compile("=\\d++"); Matcher goodsTypeMatcher ...

  9. [Usaco2008 Dec]Secret Message 秘密信息

    2794: [Usaco2008 Dec]Secret Message 秘密信息 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 7  Solved: 3 ...

  10. Voilin 与 乐谱

    小提琴属于高音乐器,所以它使用的是高音谱号: 用音的时候,线不够用,那就得上加线,或下加线. 小提琴的弦对应的五线谱的位置为: 第四弦,对应五线谱的下加两条线的下面 第三弦,对应五线谱的第一线的下面 ...