首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

怎么实现CInternetSession上载加速

2013-01-09 
如何实现CInternetSession下载加速?下载小文件还可以,可是下载大文件时速度就很慢了,,,感觉跟在网页上右键

如何实现CInternetSession下载加速?
下载小文件还可以,可是下载大文件时速度就很慢了,,,感觉跟在网页上右键“目标另存为”的速度差不多,而一些浏览器自带的下载器速度很快,差不多有4倍的下载速度,这种是通过分包下载的吗,将待下载的文件分几段下载,完成后拼接起来。这样的方式通过CInternetSession类可以实现吗?应该怎样将待下载的文件分段呢?
[解决办法]
分段下载

Asynchronous Pluggable Protocols
http://msdn.microsoft.com/en-us/library/aa767743(VS.85).aspx

有个 Passthrough APP development toolkit, 你可以下载来看看...
[解决办法]

类采用线程技术完成http下载

 作者: 博云

 博客: http://yiyunscu.blog.163.com


#ifndef DOWNLOADTHREAD_H

#define DOWNLOADTHREAD_H


#include "afx.h"

#include "WININET.H"

#include "SpecStrings.h"




#include "afxwin.h"

#include "Afxinet.h"




#include "afxdisp.h"

#include "Shlwapi.h"

#include "atlconv.h"

#ifndef DLL_API 

#define DLL_API _declspec(dllimport)

#endif


enum ERROR_CODE

{

 RETURN_SUCCESS = 0x100,    //操作成功

 RETURN_BAD_URL = 0x101,    //链接地址错误

 RETURN_TIMEOUT = 0x102,    //访问超时

 RETURN_NETLINK_ERROR = 0x103,  //网络连接错误

 RETURN_NOT_FOUND = 0x104,   //下载文件不存在 

 RETURN_CODE_ERROR = 0x105,   //密码错误

 RETURN_FILE_ERROR = 0x106,   //本地文件错误

 RETURN_THREADCLOSE_ERROR = 0x107, //结束线程错误

 RETURN_THREAD_EXIT_OK = 0x108,  //线程正常退出

 RETURN_QUEST_ERROR = 0x109,   //多线程续下载请求服务器失败

 RETURN_NOT_HTTPORFTP_QUEST = 0x110, //非HTTP或者FTP请求

 RETURN_FILESIZE_ERROR = 0x111,  //获取文件大小失败

 RETURN_UNKNOWN_ERROR = 0x112  //未知错误 

};




class DLL_API CDownloadThread

{

public:

 CDownloadThread();

 virtual ~CDownloadThread();

public:

 /******************************************************************************

 函数名称:

  GetURLFileInfo

 参数:

  lpFileURL 下载文件链接, 传入前赋值, 不能为NULL

  filename 下载文件名, 为函数运行返回, 不用在传入前赋值

  nLen 下载文件长度, 为函数运行返回, 不用在传入前赋值

 功能:

  获取下载链接的文件信息

 *****************************************************************************/

 ERROR_CODE GetURLFileInfo(LPCTSTR lpFileURL, char *sourceFileName, DWORD &nLen);

 /*****************************************************************************************************

 函数名称:

  MultiThread

 参数:

  lpSaveFileName 下载文件的保存文件名, 传入前赋值, 可以为NULL, 此时程序以获取下载文件名保存

  nLen 下载文件长度, 为函数运行返回, 传入前赋值, 可以为NULL, 此时程序以运行目录下的downloads目录保存

 功能:

  下载文件

 *****************************************************************************************************/




 ERROR_CODE MultiThreadDownloadFile(int threadCount, LPCTSTR lpSaveFileName, LPCTSTR lpSaveDirectory);



 /****************************************************************************************************

 函数名称:

  SetTimeOut

 参数:

  ConnectTimeOut 连接超时, 以秒计

  SendTimeOut 发送超时, 以秒计

  RecTimeOut 接收超时, 以秒计

 功能:

  设置下载超时

 *****************************************************************************************************/

 void SetTimeOut(DWORD ConnectTimeOut, DWORD SendTimeOut, DWORD RecTimeOut, DWORD QueryTimeOut);    




 //清除临时资源

 void CleanTempSource();

 //强制关闭下载, 并调用CleanTempSource清除临时资源

 ERROR_CODE TerminateDownload();    




 int GetThreadCount() const;      //获取最大下载线程数

 float GetDownLoadSpeed() const;     //获取下载速度

 DWORD GetNowFileSize() const;      //获取当前已下载文件大小

 COleDateTimeSpan GetElapsedTime() const;   //获取下载用时




private:

 int nMaxThreadCount;

 BOOL m_bForceReload;

 //关闭事件标志

 BOOL bExit;




 //Internet会话

 CInternetSession *session;

 COleDateTime startTime;  //开始时间

 COleDateTimeSpan elapsed; //耗时




 BOOL DownLoadComplete;   //下载完成标志

 ERROR_CODE ReturnCode;

 BOOL StartFlag;     //开始下载标志




 //协议类型

 DWORD dwType;




 //功能函数

 void URLDecodeToGB(CString &source);

 void UTF8ToGB(CString &szstr);  //UTF-8转化成GB2312 




 //下载文件信息

 LPCTSTR m_url;

 CString m_RedirectUrl;

 CString m_filename;

 CString m_SaveFileName;




 CString m_SaveDirectory; //下载文件保存目录, 如"download"

 CString m_SourceDirectory;  //下载文件保存目录, 如"download"




 DWORD m_filelength;

 




 DWORD  m_infoStatusCode; 

 float  m_transferRate;

    

 DWORD dwRecTimeOut;

 DWORD dwSendTimeOut;

 DWORD dwConnectTimeOut; 

 DWORD dwDownFileSize;

 DWORD dwPartFileSize;

 DWORD dwQueryTimeOut;




 //线程句柄

 HANDLE hQuery;    //获取信息句柄

 HANDLE *hDownloadArray;     //下载线程句柄组

 HANDLE hMerge;    //合并文件句柄

 HANDLE hMutex;    //互斥互斥对象

 HANDLE hShare;




 //多线程下载中每个线程起始下载字节

 DWORD m_StartByte;

 DWORD m_EndByte;

 int m_threadIndex;




 //获取文件信息线程

 static DWORD WINAPI GetDownloadFileInfoThread(LPVOID lpParameter);

 //合并文件线程

 static DWORD WINAPI MergerFile(LPVOID lpParameter);






 //HTTP下载函数

 ERROR_CODE GetHttpFile(LPCTSTR lpSaveFile, DWORD bStartBytes, DWORD bEndBytes);

 //FTP下载函数

 ERROR_CODE GetFtpFile(LPCTSTR lpSaveFile, DWORD bStartBytes, DWORD bEndBytes);




 //重定向检查

 ERROR_CODE OpenRedirectHttpURL(CString &strOldLocation, CInternetSession *session); 

 //设置超时线程, 因为微软中的超时设置存在BUG, 需要采线程技术解决

 //设置连接超时线程

 static DWORD WINAPI SetConnectionTimeOut(LPVOID lpParameter);

 //设置发送超时线程

 static DWORD WINAPI SetSendTimeOut(LPVOID lpParameter);

 //设置接收超时线程

 static DWORD WINAPI SetRecTimeOut(LPVOID lpParameter);




 //下载线程

 static DWORD WINAPI DownloadFileThread(LPVOID lpParameter);

 /*************************************************************************   

 *   

 *   函数名称:   

 *       CreateSourceDirectory()   

 * 

 * 参数:

 *  LPCTSTR lpDirectoryPath

 *  若为NULL, 则创建在程序运行目录下的downloads文件下, 否则创建为lpDirectoryPath目录下

 *

 *   说明:   

 *       //创建临时资源文件夹

 *   返回文件夹目录   

 *   

 *************************************************************************/

 void CreateSourceDirectory(LPCTSTR lpDirectoryPath); 

 DWORD GetProtocalType() const;

};

#endif

上面是头文件定义, 下面是cpp文件:


#define DLL_API _declspec(dllexport)




#include "DownloadThread.h"




#define BUFFER_SIZE 4095

const TCHAR szHeaders[] = _T("Accept: */*\r\nUser-Agent:  Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)\r\n");//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CDownloadFile::CDownloadFile(){    m_TimeOut = 0;    m_bForceReload = true;    m_dwThreadID = 0;    m_hNotify = NULL;    m_dwMsgID = 0;    m_wFileID = 0;}CDownloadFile::~CDownloadFile(){}




//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////




#pragma comment(lib,"Shlwapi.lib")

#pragma comment(lib,"WinInet.lib") 

#pragma comment(lib, "Shlwapi.lib")




CDownloadThread::CDownloadThread()

{

 nMaxThreadCount = 2;

 m_filelength = 0;

 dwQueryTimeOut = 30000;




 dwConnectTimeOut = 4000;    //默认连接超时为4s

 dwSendTimeOut = 4000;  //默认发送超时为4s

 dwRecTimeOut = 30000;  //默认接收超时为30s

 m_bForceReload = true; 



 dwDownFileSize = 0;

 m_transferRate = 0.0;

 bExit = false;

 DownLoadComplete = false;

 StartFlag = false;




 m_RedirectUrl.Empty();




 m_filename.Empty();

 m_filelength = 0;




 hQuery = NULL;    //获取信息句柄

 hDownloadArray = NULL;     //下载线程句柄组

 hMerge = NULL;

 hMutex = NULL;

 m_threadIndex = 1;




 session = NULL;

 m_SaveFileName.Empty();

 m_SourceDirectory.Empty();

 hShare = NULL;

}


[解决办法]
人家写的有注释的呀

热点排行