📄 downloadconn.cpp
字号:
#include ".\downloadconn.h"
#include "struct.h"
#include <process.h> /* _beginthread, _endthread */
CDownloadConn::CDownloadConn(LPTSTR lpHost,UINT port)
{
m_lpHost = lpHost;
m_port = port;
m_netFlow = CNetFlowRecoder::GetInstance();
}
CDownloadConn::~CDownloadConn(void)
{
}
/*========================================================================
增加 一个下载文件任务
lpszDownloadUrl 远程url 如: /file/
localSavePath 本地路径 如: c://download/
lpszFileName 文件名 如: index.html
调用AddTask,由AddTask负责断点续传
========================================================================*/
bool CDownloadConn::AddDownloadFile(LPCTSTR lpszDownloadUrl,LPCTSTR localSavePath,LPTSTR lpszFileName)
{
return AddTask( m_lpHost,m_port, lpszDownloadUrl,localSavePath,lpszFileName);//内部控制断点续传
}
/*========================================================================
开始整个任务的下载
========================================================================*/
void CDownloadConn::StartTask()
{
_beginthread( Run,0,(void*)this);//文件下载
_beginthread( RefreshSpeed,0,(void*)m_netFlow);//实时流量统计
}
/*========================================================================
得到下载速率
========================================================================*/
int CDownloadConn::GetRate()
{
return m_netFlow->GetCurSpeed();
}
/*========================================================================
得到下载百分比
========================================================================*/
float CDownloadConn::GetPercentage()
{
return m_netFlow->GetCurPersentage();
}
/*========================================================================
线程函数
更新下载速率
========================================================================*/
void CDownloadConn::RefreshSpeed(void* lParam)
{
CNetFlowRecoder *netFlow = (CNetFlowRecoder*)lParam;
while( !netFlow->m_isBegin)//下载还未开始,等待
{
Sleep(1);
printf("waitting\n");
}
while( !netFlow->IsCompleted() )//下载还结束,更新速率
{
netFlow->RefreshSpeed();
}
netFlow->m_iNetRate = 0;//下载结束,速率置0
}
/*========================================================================
把tssklist的任务请求发送到content server
========================================================================*/
void CDownloadConn::SendTaskRequest(list<DOWNLOADLIST*> *taskList)
{
list<DOWNLOADLIST*>::iterator taskIterator;
for(taskIterator = taskList->begin();taskIterator != taskList->end();++taskIterator)
{
CDownloadSocket *lpDownloadSocket= (*taskIterator)->downloadSocket;
CDownloadFile *lpDownloadFile = (*taskIterator)->downloadFile;
lpDownloadSocket->Connect(m_lpHost,m_port);
lpDownloadSocket->Login();
lpDownloadSocket->SendRequest(lpDownloadFile->m_lpszFileName,lpDownloadFile->m_iCurOffset);
}
}
/*========================================================================
文件下载线程函数(太长了,不怎么好^_^)
========================================================================*/
void CDownloadConn::Run(void* lParam)
{
CDownloadConn *lpThis = (CDownloadConn*)lParam;
list<DOWNLOADLIST*>::iterator taskIterator;
list<DOWNLOADLIST*> *taskList;
taskList = &(lpThis->m_taskList);
lpThis->SendTaskRequest(taskList);//发送请求
TCHAR recvBuf[RECV_BUF_SIZE];
int recvSize;
//接收文件
while(! taskList->empty() )
{
for(taskIterator = taskList->begin();taskIterator != taskList->end();++taskIterator)
{
CDownloadSocket *lpDownloadSocket= (*taskIterator)->downloadSocket;
CDownloadFile *lpDownloadFile = (*taskIterator)->downloadFile;
CInfoFile *lpInfoFile = (*taskIterator)->infoFile;
recvSize = lpDownloadSocket->RecvData(recvBuf);
if(( DOWNLOAD_ESTABLISHED == (*taskIterator)->state )||( DONWLOAD_RESUME == (*taskIterator)->state) )//刚完成建立http连接,则分析ip 头
{
RESPONSECODE response;
response = lpDownloadSocket->GetResponse(recvBuf);//得到返回状态
switch(response)
{
case CODE_ERROR:
{
//注意,没有对外通知下载失败//winfree
lpThis->RemoveTask(taskIterator);
list<DOWNLOADLIST*>::iterator tempIterator;
tempIterator = taskIterator;
taskList->erase(taskIterator);
++tempIterator;
//如果没有到链尾
if(tempIterator != taskList->end() )
{
taskIterator = tempIterator;
}
};
break;
case CODE_OK:
{
//对第一个包进行分析,处理
UINT iContentLen = 0;
iContentLen = lpDownloadSocket->GetContentLen(recvBuf);//得到下载文件长度
if( DONWLOAD_RESUME == (*taskIterator)->state)//如果是断点续传,则从记录文件的信息初始化
{
lpThis->m_netFlow->RefreshFlow(lpDownloadFile->m_iCurOffset );//把之前下载的长度加到flow中
lpThis->m_netFlow->AddTotalFlow(lpDownloadFile->m_iContentLen);//把文件长度累加到网络流量统计的下载总长度记录中
}
else
{
lpThis->m_netFlow->AddTotalFlow(iContentLen);//把文件长度累加到网络流量统计的下载总长度记录中
}
recvSize -= lpDownloadSocket->GetHeaderLen(recvBuf);//第一个包的长度要减去http头长度
lpDownloadSocket->IgnoreIpHeader(recvBuf);//删去http头
lpDownloadFile->SetContentLen(iContentLen);//设置文件长度
(*taskIterator)->state = DOWNLOAD_CONTINUE;//置为已处理s
};
break;
}
}
if((recvSize!= 0)&&(recvSize!= SOCKET_ERROR ))
{
lpThis->m_netFlow->RefreshFlow(recvSize);//流量增加s
lpDownloadFile->SaveFile(recvBuf,recvSize);//把下载的数据写到文件s
lpInfoFile->WriteProcessInfo(lpDownloadFile);
//Sleep(50);
// printf("%d\n",lpThis->m_netFlow->GetCompletedFlow());
}
else
{
printf("aaaaaaaaaaaaaaaaaa\n");
lpThis->RemoveTask(taskIterator);
taskList->erase(taskIterator);
break;//直接退出for循环,从第一个任务重新开始,为了写代码方便
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -