用了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. VS2010与SVN

    http://blog.sina.com.cn/s/blog_4fe44775010182yl.html 在VS2010中使用SVN,必须先安装SVN的客户端,再安装VisualSVN(SVN的插件) ...

  2. jsoup -- xml文档解析

    jsoup -- xml文档解析 修改 https://jsoup.org/cookbook/modifying-data/set-attributes https://jsoup.org/cookb ...

  3. jquery.mustache.js使用

    作者:zccst jquery.mustache是用jQuery做了一层封装,提供了以下几个方法,让模板使用更便捷. 1,添加模板,使用异步的方式 var viewData = { name: 'Jo ...

  4. 四、Hbase

    一.什么情况下使用Hbase 例子: 这里Order By无时不刻的处理,我们要看到刚才的足迹,不能使用缓存技巧. 根据时间戳来查询,显然很快,应为Hbase就是以时间戳来存的. 将最近的数据放在内存 ...

  5. HTML学习(三)文本格式化

    HTML文本格式化HTML 可定义很多供格式化输出的元素,比如粗体和斜体字.例1:此例演示如何在一个 HTML 文件中对文本进行格式化<html> <body> <b&g ...

  6. Java Base64、AES、SHA1、MD5加密算法(转载)

    package com.example.decript; import java.io.UnsupportedEncodingException; import java.security.Inval ...

  7. 图解 Monad

    原文地址: http://www.ruanyifeng.com/blog/2015/07/monad.html

  8. DWR3.0框架入门(3) —— ScriptSession的维护及优化

    1.ScriptSession使用中存在的问题        在上一节实现了服务器的推送功能,但是根据 ScriptSession的生命周期我们可以得出以下几点的问题:   (1)ScriptSess ...

  9. 网络请求工具--AFNetworking 分类: ios技术 2015-02-03 08:17 76人阅读 评论(0) 收藏

    在我们开发过程中,网络请求是必不可少的,对于网络框架,现在主流的大概只有三类:ASI框架: HTTP终结者(已经停止更新了),MKNetworkKit ,AFN.今天我就来浅谈一下这个AFN AFNe ...

  10. IOS开发根据字体大小等获取文字所占的高度

    Model *model = self.modelArr[indexPath.row]; //根据label文字获取CGRect NSMutableParagraphStyle *paragraphS ...