使用 CInternetSession 封装多线程 http 文件下载

MFC实现HTTP文件下载指南 MFC(Microsoft Foundation Classes)是一个用于简化Windows应用程序开发的C++库。它提供了一组封装了Windows API的类,这些类使得创建用户界面、处理输入输出以及管理应用程序资源变得更加容易。MFC被设计为一个对象框架,允许开发者利用面向对象的方法来构建应用程序。 阅读详情

使用 CInternetSession 封装多线程 http 文件下载

作者:付黎
http://www.crazy-bit.com/

源代码下载
/*

URLDownloadToFile();

主要是下载升级包..............................

*/
  如何下载一个http文件?我们当然可以用socket自己实现http协议去做,但费时费力还易出bug,对于一个客户端程序稳定易维护是第一位的,所幸MS给我们提供了功能强大的internet API函数族,MFC的CInternetSession对它们进行了一些简单的封装,但如此简单的封装对我等拿来主义者来说只是个半成品。必须经过再加工才能食用。

先来介绍一下CInternetSession的使用:

下面的代码是读取链接的基本方法:

// CInternetSession在遇到一些错误时会抛出异常,因此必须包起来
TRY
{
      CInternetSession     sess ;

      // 统一以二进制方式下载
      DWORD         dwFlag = INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD ;
      CHttpFile     * pF = (CHttpFile*)sess.OpenURL(strFilename, 1, dwFlag); ASSERT(pF);
      if (!pF)
          {AfxThrowInternetException(1);}

      // 得到文件大小
      CString        str ;
      pF->QueryInfo (HTTP_QUERY_CONTENT_LENGTH, str) ;
      int     nFileSize = _ttoi(str) ;

      char     * p = new[nFileSize] ;
      while (true)
      {
          // 每次下载8Kb
          int     n = pF->Read (p, (nFileSize < 8192) ? nFileSize : 8192) ;
          if (n <= 0)
              break ;
          p += n ; nFileSize -= n ;
      }
      delete[] p ;
      delete pF ;
}
CATCH_ALL(e) {}
END_CATCH_ALL
  这段代码有一个问题,在获取文件大小这个地方,对于静态网页 HTTP_QUERY_CONTENT_LENGTH 查询会返回文件大小,但对于asp,php这样的动态网页,查询会返回0。必须通过不断的调用 CHttpFile::GetLength 来一点一点累加内容,就像这样:
int     n = pF->GetLength() ;
while (n)
{
      int     * p = new BYTE[n] ;
      pF->Read (p, n) ;
      delete[] p ;
      n = pF->GetLength() ;
}
不过网络断线同样会让 GetLength 返回0,必须把这种情况屏蔽掉。
if (n == 0)
{
      DWORD     dw ;
      if (::InternetQueryDataAvailable ((HINTERNET)(*pF), &dw, 0, 0) && (dw == 0))
      {
          // 到这里就代表文件下载成功了
      }
}
   OK,我们已经把机制摸清了,剩下就是把这些体力活全扔进线程里,又一个麻烦产生了:线程里如何向外界通知事件(开始下载,下载完成之类)呢?直接调用回调函数当然可以,但这时回调函数是置于我们的线程中,造成在回调函数中对资源的访问必须非常小心,防止 多线程冲突。下一步,加锁同步...。
挣扎在 多线程泥潭中的人已经够多的了,其实我们有一个更安全方便的方法,借助 SendMessage 把线程里的事件发送到窗口线程统一处理,windows会帮我们把所有消息排队执行,相当于把 多线程程序转成了单线程^_^ (我一个同事把此类用于包含数百个线程的爬虫程序中,非常稳定)

封装结果及使用:
template<class T>
class FCDownloadFileWndBase : public T
{
public:
      // 默认构造函数
      FCDownloadFileWndBase () {}
      // CDialog 构造函数
      FCDownloadFileWndBase (UINT nID, CWnd* pParent) : T(nID, pParent) {}
      // CFormView 构造函数
      FCDownloadFileWndBase (UINT nID) : T(nID) {}

      // 创建一个线程下载文件URL,如果URL正在下载中,此函数什么也不做立即返回
      void DownloadFile (LPCTSTR strFileURL, int nPriority=THREAD_PRIORITY_IDLE) ;

protected:
      // 检查链接最后修改时间,有些服务器会禁止查看时间,strTime为空
      // 用户必须重载实现本接口,返回TRUE则继续下载文件,返回FALSE则不再下载文件
      virtual BOOL DownloadFile_OnCheckTime (CString strFileURL, CString strTime) =0 ;

      // 当链接成功下载完成后会调用此接口
      virtual void DownloadFile_OnFinished (CString strFileURL, char* pBuffer, int nLength) {}

      // 当IE设置代理服务器并且服务器需要帐号认证时候回调
      virtual void DownloadFile_OnProxyValidate (CString strFileURL, CString& strUsername, CString& strPassword) {}

      // 出现错误时回调
      virtual void DownloadFile_OnError (CString strFileURL) {}

      // 开始下载一个链接
      virtual void DownloadFile_OnStartDownload (CString strFileURL) {}

      // 当前进度,每下载一块数据就会回调
      virtual void DownloadFile_OnProgress (CString strFileURL, int nNow, int nTotal) {}
};
使用起来非常简单,让你的窗口从它派生,然后选择你感兴趣的事件重载之即可。

几点说明:

  1. 本类会自动使用IE里的连接设置,如果代理服务器需要帐号验证,会回调 DownloadFile_OnProxyValidate 让用户输入帐号密码;
  2. 因为使用了模版,所以不支持MFC丑陋的dynamic机制:-( ,请把 DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC 宏从你的类中移除。如果你需要运行时类型检查,可以用C++的RTTI机制dynamic_cast/typeid;
 
基于MFC的HTTP下载实战教程 本文还有配套的精品资源,点击获取 简介:该文件是一个示例程序,演示如何使用Microsoft Foundation Class (MFC) 库中的CInternetSession类实现HTTP下载功能。通过MFC框架和CInternetSession类,开发者能够创建互联网会话并管理下载过程,包括连接管理、错误处理、安全设置和缓存策略。该程序还可能包含源代码文件,如http... 阅读详情

相关推荐

利用CInternetSession类实现HTTP下载

利用CInternetSession类实现HTTP下载

使用CInternetSession封装多线程http文件下载

如何下载一个http文件?我们当然可以用socket自己实现http协议去做,但费时费力还易出bug,对于一个客户端程序稳定易维护是第一位的,所幸MS给我们提供了功能强大的internet API函数族,MFC的CInternetSession对它们进行了一些简单的封装,但如此简单的封装对我等拿来主义者来说只是个半成品。必须经过再加工才能食用。先来介绍一下CInternetSession的使用:下

dolphin98629的专栏 1174

http文件服务器 多线程 并发处理

相比之前的http文件服务器,此版本支持多线程处理响应请求,支持多请求同时下载功能,中文文件名会乱码,仅支持英文文件名称

CHttpFile下载文件小例子

利用MFC类里CHttpFile CInternetSession CFile 等实现网络下载功能

Lasuerte的博客 1988

使用线程池实现的Http上传下载实现

福利贴: 前段时间发布了《Windows下一个比较完美的线程池实现和示例》(http://download.youkuaiyun.com/detail/fishjam/5106672),根据下载量和评论来看,对大家还比较有用。 现在发布一个利用该线程池实现的Http上传下载实现,不过这几个类写的比较粗糙,比如: 1.还有很多问题没有考虑或提供解决方案(本地磁盘已有同名下载文件的处理,理论上应该通过回调由用户选择处理); 2.也有很多我想加的东西(比如 身份验证、多线程下载同一个文件等)都没有加进去, 希望大家多多包含。另外如果大家发现有什么问题或好的建议,请及时告知。我。 PS:更改了我在博客中所说的,当以 Start(0, N) 启动线程池,可能造成 Wait 超时的Bug.

C语言实现高并发http文件上传下载服务器【源码下载】VS2010工程

C 语言实现的http文件上传下载服务 系统平台:windows 开发工具:vs2010 开发语言:C 程序为单线程,使用I/O多路复用实现并发 抽取libevent的最最最基础框架,自己封装event 使用BSD tree.h的红黑树

使用CInternetSession CHttpFile下载网页链接地址的文件

思路很清晰,使用CInternetSession创建CHttpFile对象。然后对该对象获取文件信息、进行文件读写操作均可。 void DownloadFile(LPCTSTR szURL, LPCTSTR szFile) //szURL 表示网页地址 szFile 表示保存本地的路径(及要保存的文件名) 感谢网友oceansoft http://blog.chinaunix.net/uid...

weixin_33910385的博客 302

c++/MFC断点续传下载

使用CInternetSession编写的可以断点续传的http下载类,VS2010测试可用

使用 CInternetSession 封装多线程 http 文件下载(转)

如何下载一个http文件?我们当然可以用socket自己实现http协议去做,但费时费力还易出bug,对于一个客户端程序稳定易维护是第一位的,所幸MS给我们提供了功能强大的internet API函数族,MFC的CInternetSession对它们进行了一些简单的封装,但如此简单的封装对我等拿来主义者来说只是个半成品。必须经过再加工才能食用。   先来介绍一下CInternetSession的

dragoo1的专栏 2628

三角洲行动交易行自动化脚本

DFMarketBot - 三角洲行动自动交易助手 DFMarketBot是一款专为三角洲行动游戏设计的交易行自动化工具,通过OCR识别和鼠标模拟实现自动补卡、补子弹功能。项目采用Python开发,支持Windows平台,主要功能包括: 自动检测并购买指定物品(房卡/子弹) 价格监控与智能购买(低于设定价格自动下单) 自定义购买数量与次数限制 支持窗口/无窗口两种游戏模式 使用前需安装Tesseract OCR引擎并配置游戏为1920*1080分辨率。通过JSON文件可灵活配置监控物品清单、理想价格和购买策

愤怒的阿木木的博客 3万+

基于STM32智能教室灯光照明人数监测系统

本文设计了一套基于STM32和物联网技术的智能教室照明系统,通过光照传感器和双红外对管实现精准人数统计,结合"光照+人数"双条件判断实现按需照明。系统采用"感知-决策-执行-云联"架构,包含环境感知、人数统计、控制执行等模块,支持本地自动控制和手机APP远程管理。测试表明系统能有效避免"长明灯"现象,具有节能降耗、管理智能化的特点。创新点在于双向人数统计算法和双条件控制逻辑,为智慧校园建设提供了实用解决方案。

1159

CInternetSession

网络编程,CInternetSession,OpenUrl,CStdion,exe 请问用CInternetSession.OpenUrl函数和CStdion类从网站上下载一个exe文件的方法 作者:不详  来源:本站整理  发布时间:2007-1-22 8:57:56  

c0ffee1982的专栏 3281

阿里云百炼接入本地Claude,接入idea

阿里云百炼平台提供两种接入方式:未购买套餐时使用通用API Key(sk-xxxxx),需注意免费额度独立计算且不会自动切换模型;购买Coding Plan套餐后使用专属API Key(sk-sp-xxxxx),享受固定月费无超支风险。配置需在.claude/settings.json中设置认证信息,包括API Key和Base URL。建议开启"用完即停"功能避免意外扣费,不同模型的免费额度互不影响。购买套餐后还可通过IDEA插件Claude Code进行集成,实现固定费用下的稳定使用

fengtangjiang的博客 1359

CInternetSession的使用

1. CInternetSession的简单使用CInternetSession session;CHttpFile *file = NULL; CString strURL = " http://www.20abcd.com";CString strHtml = "”;   //存放网页数据 try{       file = (CHttpFile*)session.

muzi_yun的专栏 2万+

代谢组数据分析(十五):基于python语言构建PLS-DA分类预测模型

本教程阐述典型代谢组学数据分析工作流程,用于二元分类结果的研究。流程主要步骤如下:首先从 Excel 表格导入代谢物与实验数据,接着基于汇总 QC 进行数据清洗。随后借助主成分分析可视化检查数据质量,再开展两类单变量统计。之后运用偏最小二乘判别分析(PLS - DA)实施多变量分析,此过程涵盖模型优化(对比 R2 与 Q2)、置换测试及明确模型预测指标、确定特征重要性、对模型预测数据进行可视化。最终将统计表格导出至 Excel 表格,完整呈现从数据导入到分析结果输出的全过程。

专注生信领域 2875

17、激光切割质量影响因素及优化研究

本文研究了激光切割过程中焦点位置、入射角、激光功率、切割速度和气体压力等因素对切割质量的影响,采用响应面方法(RSM)和Box-Behnken设计,基于三种不同喷嘴对SS 304不锈钢进行实验。通过建立切缝宽度比和条纹深度的回归模型,并结合方差分析验证模型有效性,深入分析各参数对切割质量的影响机制。研究发现喷嘴结构差异显著影响参数作用趋势,尤其在切割速度和气体压力响应上表现明显。最终通过多目标优化确定最小激光功率、适中切割速度和最大气体压力为最优组合,显著提升切割质量,为实际生产提供了理论依据和技术支持。未

grape的博客 130

CInternetSession的简单使用

<br />CInternetSession<br />  使用类CInternetSession 创建并初始化一个或多个同时的Internet 会话。如果需要,还可描述与代理服务器的连接。如果Internet连接必须在应用过程中保持着,可创建一个类CWinApp的CInternetSession成员。一旦已建立起Internet 会话,就可调用OpenURL。CInternetSession会通过调用全局函数AfxParseURL来为分析映射URL。无论协议类型如何,CInternetSession 解释

silent_cat的专栏 4729

Linux | Ubuntu18.04安装WIFI6 AX201驱动完整教程

本节介绍了如何在Ubuntu18下安装AX201驱动的教程。

九七的博客 8881

一个下载Http文件到本地的Demo

最近在做一个项目,需要把一个internet网上的Url文件下载到本地,下面是我使用的一些代码该代码支持线程. 头文件:#pragma once#include "afxmt.h"#include "wininet.h"#define  WM_HTTP_DOWNLOAD_FINISH WM_USER + 200 enum e_Down_ErrorCode{ e_Down

海峡 专栏 1617

基于STM32的浴室环境智能控制系统设计

摘要:本文设计了一款基于STM32F103的智能卫浴系统,通过多传感器协同检测浴室环境参数。系统采用DS18B20检测环境与卫浴温度,DHT11监测湿度,MQ-135检测空气质量,光敏电阻测量光照强度,D203S人体热释电模块检测人员存在。当检测到异常参数时,系统自动启动相应调节功能:温度异常时控制加热/制冷继电器,湿度过高时启动通风除湿,空气质量差时进行换气,光照不足且有人时自动开灯。系统支持按键、蓝牙APP和语音三种控制方式,可手动设置参数阈值、切换防雾模式、控制音乐播放等功能。实验结果表明,该系统能有

3254968421的博客 483

lp–mspm0g3507开发板进入低功耗模式怎么退出?烧程序烧着烧着就进来了,跳线帽没动过,且报错:Texas Instruments Debugger Error: DAP Co...如何解决?

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 1569

CInternetSession介绍与简单使用

使用类CInternetSession 创建并初始化一个或多个同时的Internet 会话。如果需要,还可描述与代理服务器的连接。 CInternetSession CObject └CInternetSession 如果Internet连接必须在应用过程中保持着,可创建一个类CWinApp的CInternetSess

路人甲 3890

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

上一篇: 如何点对点实现多线程断点续传
下一篇: 使用WinInet API 进行异步编程
c0ffee1982
博客等级 码龄20年 9粉丝 114原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值