1、vc+ 实现多线程断点续传vc+ 实现多线程断点续传 分类: VC+编程技术 2009-04-16 10:45 1210人阅读 评论(5) 收藏 举报 结合本人的FTP类,http类,实现多线程断点续传/ DownloadMTR.cpp: implementation of the CDownloadMTR class./#include stdafx.h#include downtest.h#include DownloadMTR.h#include #ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE=_FILE_;#define new D
2、EBUG_NEW#endifvoid DownloadNotify ( int nIndex, UINT nNotityType, LPVOID lpNotifyData, LPVOID pDownloadMTR );/ Construction/Destruction/CDownloadMTR:CDownloadMTR(): m_nThreadCount ( DEFAULT_THREAD_COUNT ), m_pDownloadPub_MTR ( NULL ), m_pDownloadPub_Info ( NULL ), m_pDownloadCellInfo ( NULL ), m_hTh
3、read ( NULL ), m_bForceDownload ( FALSE ), m_nTotalDownloadedSize_ThisTimes ( 0 )memset ( &m_BaseDownInfo, 0, sizeof(t_BaseDownInfo) );m_hEvtEndModule = :CreateEvent ( NULL, TRUE, FALSE, NULL );m_dwDownloadStartTime = GetTickCount();CDownloadMTR:CDownloadMTR()StopDownload ();/ 设置下载的线程数/BOOL CDownloa
4、dMTR:SetThreadCount(int nThreadCount)if ( nThreadCount MAX_DOWNLOAD_THREAD_COUNT )Log ( L_WARNING, Thread count %d is invalid. Rang %d-%d, nThreadCount, 1, MAX_DOWNLOAD_THREAD_COUNT );return FALSE;if ( nThreadCount = m_nThreadCount )return TRUE;m_nThreadCount = nThreadCount;return TRUE;/ 下载任务的线程函数/D
5、WORD WINAPI ThreadProc_DownloadMTR( LPVOID lpParameter / thread data)CDownloadMTR *pDownloadMTR = (CDownloadMTR*)lpParameter;ASSERT ( pDownloadMTR );pDownloadMTR-ThreadProc_DownloadMTR ();TRACE ( 下载任务的线程函数 执行完毕/n );return TRUE;BOOL CDownloadMTR:ThreadProc_DownloadMTR()/ 启动多线程下载任务int nRet = StartMTRD
6、ownload ();if ( nRet = 2 ) return HandleDownloadFinished(ENUM_DOWNLOAD_RESULT_SUCCESS);if ( nRet = 0 ) return HandleDownloadFinished(ENUM_DOWNLOAD_RESULT_FAILED);/ 等待所有线程下载完成ENUM_DOWNLOAD_RESULT eDownloadResult = WaitForDownloadFinished ();if ( eDownloadResult = ENUM_DOWNLOAD_RESULT_SUCCESS & !GetDo
7、wnloadResult () )eDownloadResult = ENUM_DOWNLOAD_RESULT_FAILED;return HandleDownloadFinished ( eDownloadResult );/ 多线程断点续传下载一个文件/BOOL CDownloadMTR:Download (LPCTSTR lpszDownloadURL,LPCTSTR lpszSavePath,LPCTSTR lpszSaveOnlyFileName,LPCTSTR lpszUsername/*=NULL*/,LPCTSTR lpszPassword/*=NULL*/,BOOL bFor
8、ceDownload/*=FALSE*/ 如果为 TRUE 表示强制性重新下载,以下载的部分将会被删除,FALSE 表示断点续传)if ( !HANDLE_IS_VALID(m_hEvtEndModule) )return FALSE;if ( !lpszSavePath | strlen(lpszSavePath) SetAuthorization ( lpszUsername, lpszPassword );m_pDownloadPub_Info-m_pDownloadMTR = this;m_pDownloadPub_Info-SetDownloadUrl ( lpszDownloadU
9、RL );/ 创建一个下载线程DWORD dwThreadId = 0;m_hThread = CreateThread ( NULL, 0, :ThreadProc_DownloadMTR, LPVOID(this), 0, &dwThreadId );if ( !HANDLE_IS_VALID(m_hThread) )Log ( L_WARNING, Create download thread failed );return FALSE;return TRUE;/ 创建下载对象/CDownloadPub* CDownloadMTR:CreateDownloadObject ( int n
10、Count/*=1*/ )if ( nCount Callback_SaveDownloadInfo ( nIndex, nDownloadedSize, nSimpleSaveSize );void CDownloadMTR:Callback_SaveDownloadInfo ( int nIndex, int nDownloadedSize, int nSimpleSaveSize )if ( nIndex = 0 & nIndex 0 )m_CSFor_DownloadedData.Lock();m_nTotalDownloadedSize_ThisTimes += nSimpleSav
11、eSize;m_CSFor_DownloadedData.Unlock ();/ 创建多线程下载使用的对象和数据缓冲/BOOL CDownloadMTR:CreateDownloadObjectAndDataMTR ()DeleteDownloadObjectAndDataMTR ();ASSERT ( !m_pDownloadPub_MTR & m_pDownloadPub_Info );m_pDownloadPub_MTR = CreateDownloadObject ( m_nThreadCount );/ 设置多线程下载使用的对象的参数if ( m_pDownloadPub_MTR )
12、for ( int nIndex=0; nIndexGet_UserName(), m_pDownloadPub_Info-Get_GetPassword() );m_pDownloadPub_MTRnIndex.SetDownloadUrl ( m_csDownloadURL );if ( !m_pDownloadPub_MTRnIndex.SetSaveFileName ( GetTempFilePath() ) )return FALSE;/ 创建多线程下载使用的数据缓冲ASSERT ( !m_pDownloadCellInfo );m_pDownloadCellInfo = new t
13、_DownloadCellInfom_nThreadCount;if ( m_pDownloadCellInfo )memset ( m_pDownloadCellInfo, 0, m_nThreadCount*sizeof(t_DownloadCellInfo) );if ( m_pDownloadPub_MTR != NULL & m_pDownloadCellInfo != NULL )return TRUE;Log ( L_WARNING, Create MTR download object or buffer failed );return FALSE;/ 删除多线程下载使用的对象
14、和数据缓冲/void CDownloadMTR:DeleteDownloadObjectAndDataMTR()if ( m_pDownloadPub_MTR )DeleteDownloadObject ( m_pDownloadPub_MTR );m_pDownloadPub_MTR = NULL;if ( m_pDownloadCellInfo )delete m_pDownloadCellInfo;m_pDownloadCellInfo = NULL;/ 删除取站点信息的下载对象/void CDownloadMTR:DeleteDownloadObject_Info()if ( m_pD
15、ownloadPub_Info )DeleteDownloadObject ( m_pDownloadPub_Info );m_pDownloadPub_Info = NULL;/ 启动多线程下载,返回 0 表示失败,1表示成功,2表示不用下载了,因为该文件已经下载过了/int CDownloadMTR:StartMTRDownload ()m_dwDownloadStartTime = GetTickCount();DownloadNotify ( -1, NOTIFY_TYPE_START_DOWNLOAD, (LPVOID)NULL, this );/ 先获取站点信息ASSERT ( m
16、_pDownloadPub_Info );if ( !m_pDownloadPub_Info-GetRemoteSiteInfo () )return 0;DbgLog ( 要下载的文件大小是: %d 字节/n, m_pDownloadPub_Info-Get_FileTotalSize () );StandardSaveFileName ();CFileStatus fileStatus;if ( m_bForceDownload )/ 需要重新下载:DeleteFile ( m_csSavePathFileName );:DeleteFile ( GetTempFilePath() );e
17、lse/ 要保存的文件是否已经存在,且大小和创建时间一致,如果不是强制性下载,则不需要再下载了。if ( CFile:GetStatus(m_csSavePathFileName,fileStatus) )if(fileStatus.m_mtime.GetTime() - m_pDownloadPub_Info-Get_TimeLastModified() Get_TimeLastModified()-fileStatus.m_mtime.GetTime() Get_FileTotalSize ()&!m_bForceDownload)return 2;BOOL bMustCreateNull
18、File = TRUE;/ 读取下载信息,如果能读到说明上次下载尚未完成if ( !m_bForceDownload & m_pDownloadPub_Info-Is_SupportResume() )if ( CFile:GetStatus(GetTempFilePath(),fileStatus) &fileStatus.m_size = m_pDownloadPub_Info-Get_FileTotalSize()+GetDownloadInfoWholeSize() )if ( ReadDownloadInfo () )bMustCreateNullFile = FALSE;if (
19、bMustCreateNullFile )int nFileSize = m_pDownloadPub_Info-Get_FileTotalSize();int nTempFileSize = nFileSize+GetDownloadInfoWholeSize();if ( nFileSize Is_SupportResume() )nTempFileSize = 0;/ 创建一个用来保存下载数据的空文件if ( !CreateNullFile ( GetTempFilePath(), nTempFileSize ) )return FALSE;/ 分配下载任务if ( !AssignDow
20、nloadTask () )Log ( L_WARNING, Assign task failed );return 0;m_dwDownloadStartTime = GetTickCount();return 1;/ 得到临时数据保存的路径文件名/CString CDownloadMTR:GetTempFilePath ()ASSERT ( !m_csSavePathFileName.IsEmpty () );CString csTempFileName;csTempFileName.Format ( %s.xhw, m_csSavePathFileName );:SetFileAttri
21、butes ( csTempFileName, FILE_ATTRIBUTE_HIDDEN );return csTempFileName;/ 分配下载任务/BOOL CDownloadMTR:AssignDownloadTask()ASSERT ( m_pDownloadPub_Info );if ( !m_pDownloadPub_Info-Is_SupportResume() )DeleteDownloadObjectAndDataMTR ();Log ( L_WARNING, Site %s not support resume download, m_pDownloadPub_Info-Get_ServerName() );/ 文件大小未知,采用单线程if ( m_pDownloadPub_Info-Get_FileTotalSize () Is_SupportResume() )if ( m_nThreadCount != 1 )DeleteDownloadObjectAndDataMTR ();SetThreadCount ( 1 );if ( !DownloadInfoIsValid() | !m_pDownloadPub_MTR | !m_pDownlo
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2