vc++ 实现多线程断点续传.docx
- 文档编号:8959947
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:27
- 大小:21.27KB
vc++ 实现多线程断点续传.docx
《vc++ 实现多线程断点续传.docx》由会员分享,可在线阅读,更多相关《vc++ 实现多线程断点续传.docx(27页珍藏版)》请在冰点文库上搜索。
vc++实现多线程断点续传
vc++实现多线程断点续传
分类:
VC++编程技术2009-04-1610:
451210人阅读评论(5)收藏举报
结合本人的FTP类,http类,实现多线程断点续传
//DownloadMTR.cpp:
implementationoftheCDownloadMTRclass.
//
//////////////////////////////////////////////////////////////////////
#include"stdafx.h"
#include"downtest.h"
#include"DownloadMTR.h"
#include
#ifdef_DEBUG
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#definenewDEBUG_NEW
#endif
voidDownloadNotify(intnIndex,UINTnNotityType,LPVOIDlpNotifyData,LPVOIDpDownloadMTR);
//////////////////////////////////////////////////////////////////////
//Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDownloadMTR:
:
CDownloadMTR()
:
m_nThreadCount(DEFAULT_THREAD_COUNT)
,m_pDownloadPub_MTR(NULL)
,m_pDownloadPub_Info(NULL)
,m_pDownloadCellInfo(NULL)
,m_hThread(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();
}
//
//设置下载的线程数
//
BOOLCDownloadMTR:
:
SetThreadCount(intnThreadCount)
{
if(nThreadCount<=0||nThreadCount>MAX_DOWNLOAD_THREAD_COUNT)
{
Log(L_WARNING,"Threadcount%disinvalid.Rang[%d-%d]",nThreadCount,1,MAX_DOWNLOAD_THREAD_COUNT);
returnFALSE;
}
if(nThreadCount==m_nThreadCount)
returnTRUE;
m_nThreadCount=nThreadCount;
returnTRUE;
}
//
//下载任务的线程函数
//
DWORDWINAPIThreadProc_DownloadMTR(
LPVOIDlpParameter //threaddata
)
{
CDownloadMTR*pDownloadMTR=(CDownloadMTR*)lpParameter;
ASSERT(pDownloadMTR);
pDownloadMTR->ThreadProc_DownloadMTR();
TRACE("下载任务的线程函数执行完毕/n");
returnTRUE;
}
BOOLCDownloadMTR:
:
ThreadProc_DownloadMTR()
{
//启动多线程下载任务
intnRet=StartMTRDownload();
if(nRet==2)returnHandleDownloadFinished(ENUM_DOWNLOAD_RESULT_SUCCESS);
if(nRet==0)returnHandleDownloadFinished(ENUM_DOWNLOAD_RESULT_FAILED);
//等待所有线程下载完成
ENUM_DOWNLOAD_RESULTeDownloadResult=WaitForDownloadFinished();
if(eDownloadResult==ENUM_DOWNLOAD_RESULT_SUCCESS&&!
GetDownloadResult())
{
eDownloadResult=ENUM_DOWNLOAD_RESULT_FAILED;
}
returnHandleDownloadFinished(eDownloadResult);
}
//
//多线程断点续传下载一个文件
//
BOOLCDownloadMTR:
:
Download(
LPCTSTRlpszDownloadURL,
LPCTSTRlpszSavePath,
LPCTSTRlpszSaveOnlyFileName,
LPCTSTRlpszUsername/*=NULL*/,
LPCTSTRlpszPassword/*=NULL*/,
BOOLbForceDownload/*=FALSE*/ //如果为TRUE表示强制性重新下载,以下载的部分将会被删除,FALSE表示断点续传
)
{
if(!
HANDLE_IS_VALID(m_hEvtEndModule))
returnFALSE;
if(!
lpszSavePath||strlen(lpszSavePath)<1)
returnFALSE;
m_csSavePath=lpszSavePath;
m_csSaveOnlyFileName=GET_SAFE_STRING(lpszSaveOnlyFileName);
m_bForceDownload=bForceDownload;
CStringcsServer,csObject;
USHORTnPort=0;
if(!
ParseURL(lpszDownloadURL,csServer,csObject,nPort,m_csProtocolType))
{
Log(L_ERROR,"DownloadURL[%s]invalid",lpszDownloadURL);
returnFALSE;
}
m_csDownloadURL=lpszDownloadURL;
//创建取站点信息对象
if(!
(m_pDownloadPub_Info=CreateDownloadObject()))
{
Log(L_ERROR,"Createdownloadobjectfailed");
returnHandleDownloadFinished(ENUM_DOWNLOAD_RESULT_FAILED);
}
//设置取站点信息对象的参数
m_pDownloadPub_Info->SetAuthorization(lpszUsername,lpszPassword);
m_pDownloadPub_Info->m_pDownloadMTR=this;
m_pDownloadPub_Info->SetDownloadUrl(lpszDownloadURL);
//创建一个下载线程
DWORDdwThreadId=0;
m_hThread=CreateThread(NULL,0,:
:
ThreadProc_DownloadMTR,LPVOID(this),0,&dwThreadId);
if(!
HANDLE_IS_VALID(m_hThread))
{
Log(L_WARNING,"Createdownloadthreadfailed");
returnFALSE;
}
returnTRUE;
}
//
//创建下载对象
//
CDownloadPub*CDownloadMTR:
:
CreateDownloadObject(intnCount/*=1*/)
{
if(nCount<1)returnNULL;
CDownloadPub*pDownloadPub=NULL;
if(m_csProtocolType.CompareNoCase("http")==0)
{
pDownloadPub=(CDownloadPub*)newCDownloadHttp[nCount];
}
elseif(m_csProtocolType.CompareNoCase("ftp")==0)
{
pDownloadPub=(CDownloadPub*)newCDownloadFtp[nCount];
}
elsereturnNULL;
returnpDownloadPub;
}
//
//删除下载对象
//
voidCDownloadMTR:
:
DeleteDownloadObject(CDownloadPub*pDownloadPub)
{
if(m_csProtocolType.CompareNoCase("http")==0)
{
delete[]((CDownloadHttp*)pDownloadPub);
}
elseif(m_csProtocolType.CompareNoCase("ftp")==0)
{
delete[]((CDownloadFtp*)pDownloadPub);
}
elsedelete[]pDownloadPub;
}
voidCallback_SaveDownloadInfo(intnIndex,intnDownloadedSize,intnSimpleSaveSize,WPARAMwParam)
{
CDownloadMTR*pDownloadMTR=(CDownloadMTR*)wParam;
ASSERT(pDownloadMTR);
pDownloadMTR->Callback_SaveDownloadInfo(nIndex,nDownloadedSize,nSimpleSaveSize);
}
voidCDownloadMTR:
:
Callback_SaveDownloadInfo(intnIndex,intnDownloadedSize,intnSimpleSaveSize)
{
if(nIndex>=0&&nIndex { m_pDownloadCellInfo[nIndex].nDownloadedSize=nDownloadedSize; if(nDownloadedSize>0) { m_CSFor_DownloadedData.Lock(); m_nTotalDownloadedSize_ThisTimes+=nSimpleSaveSize; m_CSFor_DownloadedData.Unlock(); } } } // //创建多线程下载使用的对象和数据缓冲 // BOOLCDownloadMTR: : CreateDownloadObjectAndDataMTR() { DeleteDownloadObjectAndDataMTR(); ASSERT(! m_pDownloadPub_MTR&&m_pDownloadPub_Info); m_pDownloadPub_MTR=CreateDownloadObject(m_nThreadCount); //设置多线程下载使用的对象的参数 if(m_pDownloadPub_MTR) { for(intnIndex=0;nIndex { m_pDownloadPub_MTR[nIndex].m_nIndex=nIndex; m_pDownloadPub_MTR[nIndex].m_pDownloadMTR=this; m_pDownloadPub_MTR[nIndex].Set_SaveDownloadInfo_Callback(: : Callback_SaveDownloadInfo,WPARAM(this)); m_pDownloadPub_MTR[nIndex].SetAuthorization(m_pDownloadPub_Info->Get_UserName(),m_pDownloadPub_Info->Get_GetPassword()); m_pDownloadPub_MTR[nIndex].SetDownloadUrl(m_csDownloadURL); if(! m_pDownloadPub_MTR[nIndex].SetSaveFileName(GetTempFilePath())) returnFALSE; } } //创建多线程下载使用的数据缓冲 ASSERT(! m_pDownloadCellInfo); m_pDownloadCellInfo=newt_DownloadCellInfo[m_nThreadCount]; if(m_pDownloadCellInfo) memset(m_pDownloadCellInfo,0,m_nThreadCount*sizeof(t_DownloadCellInfo)); if(m_pDownloadPub_MTR! =NULL&&m_pDownloadCellInfo! =NULL) returnTRUE; Log(L_WARNING,"CreateMTRdownloadobjectorbufferfailed"); returnFALSE; } // //删除多线程下载使用的对象和数据缓冲 // voidCDownloadMTR: : DeleteDownloadObjectAndDataMTR() { if(m_pDownloadPub_MTR) { DeleteDownloadObject(m_pDownloadPub_MTR); m_pDownloadPub_MTR=NULL; } if(m_pDownloadCellInfo) { delete[]m_pDownloadCellInfo; m_pDownloadCellInfo=NULL; } } // //删除取站点信息的下载对象 // voidCDownloadMTR: : DeleteDownloadObject_Info() { if(m_pDownloadPub_Info) { DeleteDownloadObject(m_pDownloadPub_Info); m_pDownloadPub_Info=NULL; } } // //启动多线程下载,返回0表示失败,1表示成功,2表示不用下载了,因为该文件已经下载过了 // intCDownloadMTR: : StartMTRDownload() { m_dwDownloadStartTime=GetTickCount(); DownloadNotify(-1,NOTIFY_TYPE_START_DOWNLOAD,(LPVOID)NULL,this); //先获取站点信息 ASSERT(m_pDownloadPub_Info); if(! m_pDownloadPub_Info->GetRemoteSiteInfo()) return0; DbgLog("要下载的文件大小是: %d字节/n",m_pDownloadPub_Info->Get_FileTotalSize()); StandardSaveFileName(); CFileStatusfileStatus; if(m_bForceDownload) { //需要重新下载 : : DeleteFile(m_csSavePathFileName); : : DeleteFile(GetTempFilePath()); } else { //要保存的文件是否已经存在,且大小和创建时间一致,如果不是强制性下载,则不需要再下载了。 if(CFile: : GetStatus(m_csSavePathFileName,fileStatus)) { if ( ( fileStatus.m_mtime.GetTime()-m_pDownloadPub_Info->Get_TimeLastModified()<=2&& m_pDownloadPub_Info->Get_TimeLastModified()-fileStatus.m_mtime.GetTime()<=2 ) && fileStatus.m_size==m_pDownloadPub_Info->Get_FileTotalSize() && ! m_bForceDownload ) { return2; } } } BOOLbMustCreateNullFile=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(bMustCreateNullFile) { intnFileSize=m_pDownloadPub_Info->Get_FileTotalSize(); intnTempFileSize=nFileSize+GetDownloadInfoWholeSize(); if(nFileSize<0||! m_pDownloadPub_Info->Is_SupportResume()) nTempFileSize=0; //创建一个用来保存下载数据的空文件 if(! CreateNullFile(GetTempFilePath(),nTempFileSize)) returnFALSE; } //分配下载任务 if(! AssignDownloadTask()) { Log(L_WARNING,"Assigntaskfailed"); return0; } m_dwDownloadStartTime=GetTickCount(); return1; } // //得到临时数据保存的路径文件名 // CStringCDownloadMTR: : GetTempFilePath() { ASSERT(! m_csSavePathFileName.IsEmpty()); CStringcsTempFileName; csTempFileName.Format("%s.~xhw~",m_csSavePathFileName); : : SetFileAttributes(csTempFileName,FILE_ATTRIBUTE_HIDDEN); returncsTempFileName; } // //分配下载任务 // BOOLCDownloadMTR: : AssignDownloadTask() { ASSERT(m_pDownloadPub_Info); if(! m_pDownloadPub_Info->Is_SupportResume()) { DeleteDownloadObjectAndDataMTR(); Log(L_WARNING,"Site[%s]notsupportresumedownload",m_pDownloadPub_Info->Get_ServerName()); } //文件大小未知,采用单线程 if(m_pDownloadPub_Info->Get_FileTotalSize()<=0||! m_pDownloadPub_Info->Is_SupportResume()) { if(m_nThreadCount! =1) { DeleteDownloadObjectAndDataMTR(); SetThreadCount (1); } } if(! DownloadInfoIsValid()||! m_pDownloadPub_MTR||! m_pDownlo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- vc+ 实现多线程断点续传 vc 实现 多线程 断点续传