作者:magictong

日期:2018/04/09


资源下载

https://download.csdn.net/download/magictong/10370195

主要目的

1、下载文件到内存。

2、下载分片Range文件(譬如下载某个资源文件的第100字节到第150字节的内容)。

3、不需要回调线程是UI线程(有消息循环)。

适用场景

1、小文件全量下载(注:暂未支持断点续传)。

2、分片文件下载(注:下载某个文件中的一段内容)。

3、支持https协议(仅支持只需要验证服务器端的情况)。

适用系统

受限于WinHttp的支持,本库需要Windows XP SP1以上或者Windows 2000 SP3以上才能使用。

头文件介绍

1、QMTINYDL::IQMTinyDLSink接口

使用类需要从QMTINYDL::IQMTinyDLSink接口进行继承,实现它的三个虚函数(OnTinyDLComplete,OnTinyDLProgress,OnTinyDLError),OnTinyDLComplete必须实现,其它两个可以按需要实现,这个接口主要用于下载完成,下载失败,下载出错,下载进度的回调,使用者只有通过此接口的回调感知下载库的工作进度。回调函数参数说明参考下面的注释。

//-------------------------------------------------------------------------

// 类名     : IQMTinyDLSink

// 功能     : QMTinyDL下载回调接口

// 附注     :使用IQMTinyDLMgr接口进行下载的类需要继承本接口

// -------------------------------------------------------------------------

class IQMTinyDLSink

{

public:

virtual ~IQMTinyDLSink() {}

//-------------------------------------------------------------------------

// 函数     :OnTinyDLComplete

// 功能     :下载结束回调(dwErr==0表示下载成功)

// 返回值  : virtualvoid

// 参数     : LONGlTaskID任务id

// 参数     : void*pBuffer如果是下载到内存需求,则指向该内存,如果是下载到文件,则指向(wchar*)文件路径

// 参数     : DWORDdwSize下载总长度

// 参数     : DWORDdwErr错误码

// 参数     : PVOIDpContext上下文参数

// 附注     :必须实现

//-------------------------------------------------------------------------

virtual void OnTinyDLComplete(LONG lTaskID, void* pBuffer, DWORD dwSize,DWORD dwErr, PVOID pContext) = 0;

//-------------------------------------------------------------------------

// 函数     :OnTinyDLProgress

// 功能     :下载进度回调

// 返回值  : virtualvoid

// 参数     : LONGlTaskID任务id

// 参数     : DWORDdwLen当前下载长度

// 参数     : DWORDdwTotalLen需要下载总长度

// 参数     : PVOIDpContext上下文参数

// 附注     :可选实现

//-------------------------------------------------------------------------

virtual void OnTinyDLProgress(LONG lTaskID, DWORD dwLen, DWORDdwTotalLen, PVOID pContext) {}

//-------------------------------------------------------------------------

// 函数     :OnTinyDLError

// 功能     :下载中途错误回调

// 返回值  : virtualvoid

// 参数     : LONGlTaskID任务id

// 参数     : DWORDdwErr错误码

// 参数     : PVOIDpContext上下文参数

// 附注     :可选实现

//-------------------------------------------------------------------------

virtual void OnTinyDLError(LONG lTaskID, DWORD dwErr, PVOID pContext) {}

};

//-------------------------------------------------------------------------

// 枚举名  : ERRORCODE

// 功能     :下载失败错误码

// 附注     :通过DWORD dwErr参数传递

//-------------------------------------------------------------------------

enum

{

ERRORCODE_NULL=0,                       //SUCCESS

ERRORCODE_NOMODIFIED = 1,  // Nomodified . so no update

ERRORCODE_NETWORKFAILED = 2,

ERRORCODE_OPEN_HTTP = 3,

ERRORCODE_FILE_ERROR = 4,

ERRORCODE_USER_ABORT = 5,

ERRORCODE_FAILED = 6,

//

// 创建下载实例失败,申请buffer失败等

// add by magictong 2016/12/16 11:33:33

//

ERRORCODE_CREATE_HTTPDOWNLOAD_FAILED = 7,

ERRORCODE_NEWBUF_FAILED = 8,

ERRORCODE_STOP_HANDLE_NULL = 9,

ERRORCODE_NOT_SUPPORT_WINHTTP = 10,

};

2、QMTINYDL:: IQMTinyDLMgr

使用类进行下载请求前,需要先获得QMTINYDL:: IQMTinyDLMgr接口,该接口由4个启动方法,1个反注册接口,2个停止方法和1个代理设置接口组成。详细参数信息参考下面的对应注释。

//-------------------------------------------------------------------------

// 类名     : IQMTinyDLMgr

// 功能     : QMTinyDL外部使用接口

// 附注     :

// -------------------------------------------------------------------------

class IQMTinyDLMgr

{

public:

~IQMTinyDLMgr() {}

//-------------------------------------------------------------------------

// 函数     :CHTTPDownloadEx::StartTaskToBuf

// 功能     :下载到内存,需要设置大小

// 返回值  : DWORD任务id(当前进程唯一)

// 参数     :IQMTinyDLSink* pCallbackObj回调接口

// 参数     :LPCWSTR pUrl下载链接

// 参数     :DWORD64 dw64Size下载大小

// 参数     : PVOIDpContext上下文参数

// 附注     :注意:需要设置大小,内部需要提前分配内存

//-------------------------------------------------------------------------

virtual DWORD StartTaskToBuf(

IQMTinyDLSink* pCallbackObj,

LPCWSTR pUrl,

DWORD64 dw64Size,

PVOID pContext = NULL) = 0;

//-------------------------------------------------------------------------

// 函数     :CHTTPDownloadEx::StartRangeTaskToBuf

// 功能     :下载到内存,分片下载

// 返回值  : DWORD任务id(当前进程唯一)

// 参数     :IQMTinyDLSink* pCallbackObj回调接口

// 参数     :LPCWSTR pUrl下载链接

// 参数     :DWORD64 dw64Offset下载偏移(0开始)

// 参数     :DWORD64 dw64Size下载分片大小

// 参数     : PVOIDpContext上下文参数

// 附注     :如果启动失败,则返回0,否则返回任务ID

//-------------------------------------------------------------------------

virtual DWORD StartRangeTaskToBuf(

IQMTinyDLSink* pCallbackObj,

LPCWSTR pUrl,

DWORD64 dw64Offset,

DWORD64 dw64Size,

PVOID pContext = NULL) = 0;

//-------------------------------------------------------------------------

// 函数     :CHTTPDownloadEx::StartTaskRange

// 功能     :进行下载,下载到文件

// 返回值  : DWORD任务id(当前进程唯一)

// 参数     :IQMTinyDLSink* pCallbackObj回调接口

// 参数     :LPCWSTR pUrl下载链接

// 参数     :LPCWSTR lpFilePath下载到目标文件全路径

// 参数     : PVOIDpContext上下文参数

// 附注     :如果启动失败,则返回0,否则返回任务ID

//-------------------------------------------------------------------------

virtual DWORD StartTask(

IQMTinyDLSink* pCallbackObj,

LPCWSTR pUrl,

LPCWSTR lpFilePath,

PVOID pContext = NULL) = 0;

//-------------------------------------------------------------------------

// 函数     :CHTTPDownloadEx::StartRangeTask

// 功能     :进行分片下载

// 返回值  : DWORD任务id(当前进程唯一)

// 参数     :IQMTinyDLSink* pCallbackObj回调接口

// 参数     :LPCWSTR pUrl下载链接

// 参数     :LPCWSTR lpFilePath下载到目标文件全路径

// 参数     :DWORD64 dw64Offset下载偏移(0开始)

// 参数     :DWORD64 dw64Size下载分片大小

// 参数     : PVOIDpContext上下文参数

// 附注     :如果启动失败,则返回0,否则返回任务ID

//-------------------------------------------------------------------------

virtual DWORD StartRangeTask(

IQMTinyDLSink* pCallbackObj,

LPCWSTR pUrl,

LPCWSTR lpFilePath,

DWORD64 dw64Offset,

DWORD64 dw64Size,

PVOID pContext = NULL) = 0;

//-------------------------------------------------------------------------

// 函数     :StopTask

// 功能     :停止id为lTaskID的下载任务

// 返回值  : void

// 参数     : LONGlTaskID

// 附注     :

// -------------------------------------------------------------------------

virtual void StopTask(LONG lTaskID) = 0;

//-------------------------------------------------------------------------

// 函数     :StopAllTask

// 功能     :停掉所有的下载任务

// 返回值  : void

// 附注     :

//-------------------------------------------------------------------------

virtual void StopAllTask() = 0;

//-------------------------------------------------------------------------

// 函数     :SetProxy

// 功能     :设置代理信息

// 返回值  : virtualvoid

// 参数     :QMTINYDL::QMDLPROXYTYPE proxyType,

// 参数     : PCWSTRlpszAddress

// 参数     : USHORTusPort

// 参数     :LPCWSTR lpszUserName = NULL

// 参数     :LPCWSTR lpszPassword = NULL

// 参数     :LPCWSTR lpszDomain = NULL

// 附注     :如果不调用SetProxy,组件内部会自动处理管家代理

//-------------------------------------------------------------------------

virtual void SetProxy(

QMTINYDL::QMDLPROXYTYPE proxyType,

LPCWSTR lpszAddress,

USHORT usPort,

LPCWSTR lpszUserName = NULL,

LPCWSTR lpszPassword = NULL,

LPCWSTR lpszDomain = NULL) = 0;

//-------------------------------------------------------------------------

// 函数     :UnregisterCallback

// 功能     :反注册回调

// 返回值  : virtualBOOL

// 参数     :IQMTinyDLSink* pCallbackObj

// 附注     :

//-------------------------------------------------------------------------

virtual BOOL UnregisterCallback(IQMTinyDLSink* pCallbackObj) = 0;

};

3、头文件里面QMDLProxyInfo和QMDLPROXYTYPE定义是代理相关内容,按需使用即可,另外库内部初始化时会自动处理IE设置的代理,如果外部调用SetProxy方法手动设置代理,则使用手动设置的代理。

使用方法

1、实现QMTINYDL::IQMTinyDLSink接口,相关调用者自己按需实现即可。

2、获得QMTINYDL:: IQMTinyDLMgr接口,获取该接口有两个方法:

(1)    一种是直接使用QMTinyDL.dll(MD编译)的导出函数获取:

//

// Export原型如下

//

extern "C" IQMTinyDLMgr*__stdcall CreateQMTinyDLMgr();

extern "C" int __stdcallDestroyQMTinyDLMgr(IQMTinyDLMgr* p);

extern "C" unsigned int__stdcall GetQMTinyDLVer();

先使用CreateQMTinyDLMgr获得IQMTinyDLMgr接口,使用完之后调用DestroyQMTinyDLMgr释放。

(2)    另外一种方法是使用QMTINYDL库的辅助lib(QMTinyDLLib.lib:MD编译)来获取,节省寻找加载QMTinyDL.dll的操作。

使用该lib只需要引入IQMTinyDL.h头文件,使用里面的两个函数CreateQMTinyDLMgr和DestroyQMTinyDLMgr即可。

//-------------------------------------------------------------------------

// 函数     : CreateQMTinyDLMgr

// 功能     :创建IQMTinyDLMgr接口

// 返回值  : IQMTinyDLMgr*

// 附注     :

//-------------------------------------------------------------------------

extern "C" IQMTinyDLMgr*__stdcall CreateQMTinyDLMgr();

// -------------------------------------------------------------------------

// 函数     : DestroyQMTinyDLMgr

// 功能     :释放IQMTinyDLMgr接口

// 返回值  : int

// 参数     : IQMTinyDLMgr* p

// 附注     :

//-------------------------------------------------------------------------

extern "C" int __stdcall DestroyQMTinyDLMgr(IQMTinyDLMgr*p);

注意:在使用QMTINYDL:: IQMTinyDLMgr接口的Start*系列方法(譬如:StartRangeTask)时,传入了一个QMTINYDL::IQMTinyDLSink接口,在调用DestroyQMTinyDLMgr之前需要把该接口从库里面反注册,务必调用QMTINYDL:: IQMTinyDLMgr接口的UnregisterCallback方法将其反注册,否则如果实现QMTINYDL::IQMTinyDLSink接口的外部对象提前销毁,极易导致下载库Crash,这里没有使用引用计数来管理各个对象主要是基于简单轻便的考虑。

使用举例

1、头文件。

class CDeltaDlder

:public QMTINYDL::IQMTinyDLSink

,public DeltaTaskBase

{

public:

CDeltaDlder(void);

~CDeltaDlder(void);

……

// -------------------------------------------------------------------------

// IQMTinyDLSink

//

virtual void OnTinyDLComplete(LONG lTaskid, void* pBuffer, DWORD dwSize,DWORD dwErr, PVOID pContext);

virtual void OnTinyDLProgress(LONG lTaskID, DWORD dwLen, DWORDdwTotalLen, PVOID pContext) {}

virtual void OnTinyDLError(LONG lTaskID,DWORD dwErr, PVOID pContext) {}

……

private:

QMTINYDL::IQMTinyDLMgr* m_pHttpDlder;

……

};

2、实现文件

BOOL CDeltaDlder::Init()

{

……

BOOLbRet = FALSE;

if(!m_pHttpDlder)

{

m_pHttpDlder = QMTINYDL::CreateQMTinyDLMgr();

}

if(!m_pHttpDlder)

{

LOG_ERROR_PRINTF(_T("[%s]QMTINYDL::CreateQMTinyDLMgr Error"), __FUNCTIONW__);

bRet= FALSE;

}

else

{

bRet= TRUE;

}

returnbRet;

}

VOID CDeltaDlder::UnInit()

{

if (m_pHttpDlder)

{

LOG_COMMON_PRINTF(L"[%s] UnInit()", __FUNCTIONW__);

m_pHttpDlder->UnregisterCallback(this);

QMTINYDL::DestroyQMTinyDLMgr(m_pHttpDlder);

m_pHttpDlder = NULL;

}

}

void CDeltaDlder::OnTinyDLComplete(LONGlTaskid, void* pBuffer, DWORD dwSize, DWORD dwErr, PVOID pContext)

{

utils::CCriticalSection::Ownero(m_csDL);

BOOL bDoTry = FALSE;

if(QMTINYDL::ERRORCODE_NULL != dwErr && lTaskid) //

{

……

}

……

}

……

DWORD dwTaskId = m_pHttpDlder->StartRangeTask(this, m_strDldUrl,itr->strDldFileName, itr->dw64DldOffset, itr->dw64DldLength);

……

一个基于WinHttp的轻量级的分片下载库介绍相关推荐

  1. 一个基于EntityFrameworkCore+Lucene实现的全文搜索引擎库

    一说到全文搜索,大家都可能会想到ES中间件,毕竟ES非常强大.对于复杂全文搜索场景ES非常好用,但是对于一些简单业务场景的,比如实现通过关键字检索文章,使用ES就显得比较重.今天就给大家推荐一个基于E ...

  2. pd.fjs分片下载的介绍2:分片下载demo

    上一个章节,简要说了以下分片下载的几个特性.今天主要用示例说明一下pdf.js分片下载. 服务器环境: php7.2 nginx 1.14 ubuntu 18.04 测试浏览器:谷歌浏览器 70.0. ...

  3. PDF.js 分片下载的介绍2:分片下载demo

    上一个章节,简要说了以下分片下载的几个特性.今天主要用示例说明一下pdf.js分片下载. 服务器环境: php7.2 nginx 1.14 ubuntu 18.04 测试浏览器:谷歌浏览器 70.0. ...

  4. 基于WPF的Metro风格的MehApp库介绍

    基本情况 是一个基于WPF的,开源的Metro风格的第三方库. 官方介绍网站在这里https://mahapps.com/,其源码在GitHubhttps://github.com/MahApps/M ...

  5. php在线播放bt,yunBT:一个基于ThinkCMS的多用户BT离线下载程序,支持在线播放

    说明:yunBT这个项目其实很早就有了,只是老没更新,现在作者基于ThinkCMS重做该程序,支持多用户注册下载,Magnet和HTTP下载.每个单独用户支持10个任务,默认下载文件最大为10GB,可 ...

  6. 一个基于BCH的付费电驴下载的设想

    作者新浪微博:中本蒜-袁维 感觉不比ipfs和joystream差 ​​​刚刚吃饭,想到了一个付费下载的解决方案,可以把电驴和BCH结合在一起. 虽然目前有ipfs和joystream,但是前者似乎也 ...

  7. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(八)RTP音视频传输解析层之MPA传输格式...

    一.MPEG RTP音频传输 相较H264的RTP传输格式,MPEGE音频传输格式则简单许多. 每一包MPEG音频RTP包都前缀一个4字节的Header,如下图(RFC2550) "MBZ& ...

  8. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——收流篇:(四)example代码解析...

    --------------------更新2018.08.20------------------- 添加http_tunnel_example.cpp作为RtspOverHttp示例程序. --- ...

  9. bodhi linux 安装 ubuntu软件,Bodhi Linux 5.1.0 发布,基于Ubuntu的轻量级发行版

    Bodhi Linux是基于Ubuntu的轻量级发行版,具有Moksha桌面环境.现在有很多Linux发行版.有些是独特的,但很多是重复的,可能没有存在的必要.由于使用了Moksha桌面环境,一个基于 ...

  10. 基于 Vue 的轻量级静态网站生成器 VuePress

    Vue.js 的创始人尤雨溪大大在 twitter 上发布了一个全新的基于 Vue 的静态网站生成器-,这对于广大 Vue 爱好者来说无疑是一个好消息! 什么是VuePress VuePress由两部 ...

最新文章

  1. 求凸包(两遍扫描,求上下凸包的方法)
  2. Struts2数据封装
  3. mac matlab 中文乱码,MAC让Matlab编辑器显示中文的方法
  4. Android 系统(211)---Power键不亮屏分析方法
  5. springboot--多环境
  6. 移动硬盘提示数据错误循环冗余检查的文件恢复方案
  7. html火焰字效果,ps怎样制作燃烧的火焰字 巧用图层样式给字体增加火焰特效教程...
  8. Windows中texstudio的主题代码(持续更新)
  9. 计算机表格里的隐藏怎么弄出来怎么办,电脑表格隐藏不见了怎么办
  10. 关于接口幂等性问题的简单总结
  11. 7-35 英文字母的大小写转换
  12. Ubuntu16.04如何设置自动休眠时间
  13. 全球投资者聚焦阿里巴巴新零售:天猫力量定义商业未来
  14. 皮卡丘(pikachu)越权漏洞
  15. WindowsForm 入门
  16. 电报电话的原理和作用
  17. C#:使用Spire.xls写Excel数据
  18. ECshop文件结构说明
  19. 北京市普通公路配齐交通诱导屏
  20. 电梯调度问题模型分析及程序设计(一)

热门文章

  1. 魔兽按键精灵 V2.0(修正1)
  2. 计算机专业助我成长作文600,挫折助我成长作文(精选6篇)
  3. 生成1-100随机数并进行猜测
  4. 元宇宙地产演化史:从文本时代到区块链时代
  5. linux rm命令 安装,Linux rm 命令 command not found rm 命令详解 rm 命令未找到 rm 命令安装 - CommandNotFound ⚡️ 坑否...
  6. c++11新特性介绍
  7. 电商运营数据分析常用分析指标--概述及流量指标
  8. excel自动求和_excel自动求和你会吗?更改姓名自动算出总分,三个函数轻松搞定...
  9. AI机器学习面试常见问题与答案
  10. 2022-9-28 c高级的复习