博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MultiThreadDownLoad
阅读量:4048 次
发布时间:2019-05-25

本文共 12094 字,大约阅读时间需要 40 分钟。

UINT ThreadFunc(LPVOID lpParam)
{
threadInfo* pInfo=(threadInfo*)lpParam;
//sess.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT,6000);
//sess.SetOption(INTERNET_OPTION_CONNECT_BACKOFF,500);  
//sess.SetOption(INTERNET_OPTION_CONNECT_RETRIES,  5);
for(UINT n = 0; n < pInfo->vecUrlFile.size(); n++)
{
EnterCriticalSection(&g_mutex);
CInternetSession sess; 
//CInternetSession::SetCookie(pInfo->vecUrlFile[n].GetBuffer(),_T("tt"),_T("tt"));
DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD;  
CHttpFile* pHttpFile = (CHttpFile* )sess.OpenURL(pInfo->vecUrlFile[n].GetBuffer(), 1, dwFlag);  //?
if (!pHttpFile)  
{
AfxMessageBox(_T("下载失败"));
return -1;  
}
DWORD dwHttpStatus = 0; 
if(!pHttpFile-> QueryInfoStatusCode(dwHttpStatus))
{
AfxMessageBox(_T("下载失败2"));
return -1;
}
if(dwHttpStatus <   200 ||   dwHttpStatus   >=   300)
{
AfxMessageBox(_T("下载失败3"));
return -1;
}
DWORD dwFileSize;
pHttpFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, dwFileSize);  
//DWORD  = pInfo->dwFileSize;
LeaveCriticalSection(&g_mutex);
char* pbuff = new char[4096];
CString sFilePath = pInfo->strFilePath + pInfo->vecFile[n];
CFile file(sFilePath.GetBuffer(),CFile::modeWrite|CFile::typeBinary|CFile::modeCreate);//下载服务器更新包到本地//
//FILE* file = _wfsopen(sFilePath.GetBuffer(),L"wb",_SH_DENYRD);
//assert(file);
//pHttpFile->SetReadBufferSize(4096);
MultiThread Concurrent Download
//EnterCriticalSection(&g_mutex);
int tt = 0;
while(dwFileSize > 4096)
{
pHttpFile->Read(pbuff,4096);
file.Write(pbuff,4096);//
//fwrite(pbuff,1,4096,file);
pInfo->dwCurSize += 4096;
dwFileSize -= 4096;
tt++;
if(tt > 3000)
{
//Sleep(1);
tt = 0;
}
}
if(dwFileSize > 0)
{
pHttpFile->Read(pbuff,dwFileSize);
file.Write(pbuff,dwFileSize);//
//fwrite(pbuff,1,dwFileSize,file);
pInfo->dwCurSize += dwFileSize;
}
//LeaveCriticalSection(&g_mutex);
file.Close();//
//fclose(file);
//EnterCriticalSection(&g_mutex);
pHttpFile->Close();  
delete pHttpFile;  
sess.Close();
//LeaveCriticalSection(&g_mutex);
delete []pbuff;  
Sleep(1);
}
pInfo->bFinish = true;
return 0;
}
UINT ThreadFunc2(LPVOID lpParam)
{
threadInfo* pInfo=(threadInfo*)lpParam;
    CInternetSession sess;  
  
//==============================读取config文件================================ 
    const char* chName;
//-------------------------------read-client-----------------------------
CreateDirectory(_T("Version"),NULL);//when version doesn't exist create this directory.
MeXmlDocument xCMeXml;
    if ( !xCMeXml.LoadFile("Version/Version.cfg", 1 ) )
//读本地版本
    { 
cstrCVersion = "";
//
return false; 
}
else
{
MeXmlElement* pCRoot = xCMeXml.FirstChildElement( "Project" );
if ( pCRoot == NULL )
AfxMessageBox(_T("读取project失败"));
return false; 
}
if((chName = pCRoot->Attribute("Version")) == NULL)
//需不需要判断空??
{
AfxMessageBox(_T("读取Version失败"));
return false;
}
cstrCVersion = chName;
}
//==================================================================================================
DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD;  
DWORD strLength;
CHttpFile* pHttpFile = (CHttpFile* )sess.OpenURL(_T("http://192.168.1.55/test/Version.cfg"), 1, dwFlag);  //下载服务器版本
    if (!pHttpFile)
{
AfxMessageBox(_T("下载服务器版本失败"));
        return -1;  
}
DWORD dwHttpStatus = 0; 
if(!pHttpFile-> QueryInfoStatusCode(dwHttpStatus))
{
AfxMessageBox(_T("下载服务器版本失败2"));
return -1;
}
if(dwHttpStatus <   200 ||   dwHttpStatus   >=   300)
{
AfxMessageBox(_T("下载服务器版本失败3"));
return -1;
}
pHttpFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, strLength);  
char* pbuff = new char[strLength+1];
pHttpFile->Read(pbuff,strLength);
    pHttpFile->Close();  
    delete pHttpFile;  
pbuff[strLength] = 0;
char* pbk = new char[strLength+1];
memcpy(pbk,pbuff,strLength+1);
MeXmlDocument doc;
doc.Parse(pbk);
MeXmlElement* pSRoot = doc.FirstChildElement( "Project" );
if ( pSRoot == NULL )
AfxMessageBox(_T("读取project失败2"));
return false; 
}
if((chName = pSRoot->Attribute("Version")) == NULL)
{
AfxMessageBox(_T("读取Version失败2"));
return false;
}
cstrSVersion = chName;
delete[]pbk;
写入临时本地版本
//CFile file(_T("Version/TmpVersion.cfg"),CFile::modeWrite|CFile::typeBinary|CFile::modeCreate);//下载服务器版本到本地
//file.Write(pbuff,strLength);
//file.Flush();
//file.Close();
//==============================读取config文件================================ 
-------------------------------read-server-------------------------------------
//MeXmlDocument xSMeXml;
 //   if ( !xSMeXml.LoadFile("Version/TmpVersion.cfg", 1 ) )
 //   { 
//
return false; 
//}
//-----------------------------------------------------
//==================================================================================================
//
if((dCVersion-dSVersion)<0.0001&&(dCVersion-dSVersion)>-0.0001)
//比较本地版本与服务器版本
//
if(strCVersion == strSVersion))//比较本地版本与服务器版本
if(cstrCVersion.Compare(cstrSVersion) == 0)//比较本地版本与服务器版本
{
//允许进入游戏。
CButton* pbut = (CButton*)pInfo->pDlg->GetDlgItem(IDOK);
//
pbut->SetWindowText(_T("启动"));
pbut->EnableWindow(TRUE);
pInfo->pDlg->GetDlgItem(IDCANCEL)->EnableWindow(TRUE);//ENABLE CANCEL
pbut->UpdateWindow();
pInfo->pDlg->UpdateWindow();
//m_btn.EnableWindow();
//不能再调用以下
//m_bmpBtn.LoadBitmaps(IDB_BIT_UP,IDB_BIT_DOWN,0,IDB_BIT_DSA);//,IDB_BMP_FOCUS,IDB_BMP_DISABLE
//m_bmpBtn.SubclassDlgItem(IDOK ,pInfo->pDlg );//(CStandardDialog*)
//m_bmpBtn.SizeToContent();
}
else
{
//先下载更新后方可进入游戏
unsigned _int64 dwTotalSize = 0;
//---------------
DownList();
if(mapFile.size() == 0)
{
AfxMessageBox(_T("DownList失败"));
return -1;
}
//-----------------------
threadInfo* tInfo = new threadInfo[MAXTHREADNUM];
for(int y=0;y<MAXTHREADNUM;y++)
{
threadInfo* pti = &tInfo[y];
pti->dwCurSize = 0;
pti->dwFileSize = 0;
pti->bFinish = false;
//tInfo[l].bFinish = false;?
pti->strFilePath = cstrRootDir;
}
int iNum = 0;
std::map<CString,SFileName>::iterator it  = mapFile.begin();
for(;it != mapFile.end();++it)
{
if(cstrRemType == it->second.strFlag)
{
continue;
}
int idx = iNum % MAXTHREADNUM;
threadInfo* pti = &tInfo[idx];
iNum++;
CInternetSession sess;  
DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD;  
CString sAddress = cstrRootURL + cstrCVersion + _T("-") + cstrSVersion + _T("/") + it->first;//1.0-3.0
//
CString sAddress = cstrRootURL + vecFile[l];
CHttpFile* pHttpFile = (CHttpFile* )sess.OpenURL(sAddress.GetBuffer(), 1, dwFlag);  
if (!pHttpFile)  
{
AfxMessageBox(_T("获取文件大小失败"));
assert(0);
return -1;
DWORD dwHttpStatus = 0; 
if(!pHttpFile-> QueryInfoStatusCode(dwHttpStatus))
{
AfxMessageBox(_T("获取文件大小失败2"));
return -1;
}
if(dwHttpStatus <   200 ||   dwHttpStatus   >=   300)
{
AfxMessageBox(_T("获取文件大小失败3"));
return -1;
}
DWORD strLength;
pHttpFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, strLength);  
dwTotalSize += strLength;
pHttpFile->Close();  
delete pHttpFile;  
pti->dwFileSize += strLength;
//?
//pti->pHttpFile = pHttpFile;
//pti->strUrlFilePath = 
pti->vecUrlFile.push_back(sAddress);
pti->vecFile.push_back(it->first);
}
pInfo->pctrlProgress->SetRange32(0,dwTotalSize);
for(int y=0;y<MAXTHREADNUM;y++)
{
threadInfo* pti = &tInfo[y];
if(pti->vecUrlFile.size() > 0)
{
AfxBeginThread(ThreadFunc,static_cast<LPVOID>(pti));
}
}
while(1)
{
bool bfinish = true;
DWORD dwsize = 0;
for (int t = 0; t < MAXTHREADNUM; ++t)
{
if(tInfo[t].vecUrlFile.size() == 0)
continue;
if(!tInfo[t].bFinish)
{
bfinish = false;
}
dwsize += tInfo[t].dwCurSize;
}
if(bfinish)
{
break;
}
else
{
pInfo->pctrlProgress->SetPos(dwsize);
}
Sleep(10);
}
delete []tInfo;
//在这里全部文件下载完成。
kwFilePath path;
//把新加文件拷贝到游戏目录
//把已有文件进行合并
for(it = mapFile.begin();it != mapFile.end();++it)
{
if(it->second.strFlag == L"Dec")
{
IPacketLib* pLib = g_CreatePackLib();
pLib->Decompress("Client\\");//释放Client.patch包里面的文件到Client目录
g_ReleasePackLib(pLib);
}
if(it->second.strFlag == L"Mod")
{
path.Split(it->second.name.c_str());
std::string share = "Data\\";
share += path.GetFileName();
IPacketLib* pLib = g_CreatePackLib();
std::string strSrcFile = share;
strSrcFile += ".pkt";
pLib->OpenPacket(strSrcFile.c_str());
share = "Version\\";
std::string strDstFile = share + it->second.name;
pLib->MegrePacketFile(strDstFile.c_str());
g_ReleasePackLib(pLib);
}
}
it  = mapFile.begin();
for(;it != mapFile.end();++it)
{
if(it->second.strFlag == L"Add")
{
//合并type属性为Add的文件
std::string src = "Version\\";
std::string dst = "Data\\";
std::string strSrcFile = src + it->second.name;
std::string strDstFile = dst + it->second.name;
if(::_access(strDstFile.c_str(),0) == 0)
{
::DeleteFileA(strDstFile.c_str());
}
assert(::MoveFileA(strSrcFile.c_str(),strDstFile.c_str()));
}
}
//删除本地文件
it  = mapFile.begin();
for(;it != mapFile.end();++it)
{
if(it->second.strFlag == L"Rem")
{
//删除type属性为Rem的文件
std::string dst = "Data\\";
std::string strDstFile = dst + it->second.name;
if(::_access(strDstFile.c_str(),0) == 0)
{
::DeleteFileA(strDstFile.c_str());
}
//assert(::DeleteFileA(strDstFile.c_str()));
}
if(it->second.strFlag == L"Mod")
{
std::string src2 = "Version\\";
std::string strDstFile2 = src2 + it->second.name;
if(::_access(strDstFile2.c_str(),0) == 0)
{
::DeleteFileA(strDstFile2.c_str());
}
}
}
//delete FileList.cfg
if(::_access("Version\\FileList.cfg",0) == 0)
{
::DeleteFileA("Version\\FileList.cfg");
}
//最后更新本地版本与服务器版本一致
//CFile file(_T("Version/Version.cfg"),CFile::modeWrite|CFile::typeBinary|CFile::modeCreate);//下载服务器版本到本地
//file.Write(pbuff,strLength);
//file.Flush();
//file.Close();
CButton* pbut = (CButton*)pInfo->pDlg->GetDlgItem(IDOK);
//pbut->SetWindowText(_T("启动"));
isWndDisable = pbut->EnableWindow(TRUE);
m_btn2.SetIcon(IDI_STAO,IDI_STAN);
//pInfo->pDlg->GetDlgItem(IDCANCEL)->EnableWindow(TRUE);//ENABLE CANCEL
pbut->UpdateWindow();
pInfo->pDlg->UpdateWindow();
//m_btn.EnableWindow();
}
delete[]pbuff;
return 0;
}
void DownList()
{
CInternetSession sess;  
DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD;  
CString csDir = cstrRootURL + cstrCVersion + _T("-") + cstrSVersion + _T("/FileList.cfg");//1.0-3.0
DWORD strLength;
CHttpFile* pHttpList = (CHttpFile* )sess.OpenURL(csDir, 1, dwFlag);  
    if (!pHttpList)
{
 
AfxMessageBox(_T("下载FileList失败"));
       return;  
}
DWORD dwHttpStatus = 0; 
if(!pHttpList-> QueryInfoStatusCode(dwHttpStatus))
{
 
AfxMessageBox(_T("下载FileList失败2"));
return ;
}
if(dwHttpStatus <   200 ||   dwHttpStatus   >=   300)
{
 
AfxMessageBox(_T("下载FileList失败3"));
return ;
}
  
    pHttpList->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, strLength);  
char* pbuff = new char[strLength];
pHttpList->Read(pbuff,strLength);
    pHttpList->Close();  
    delete pHttpList;  
//写入临时本地版本
//CreateDirectory(_T("Updates"),NULL);//when version doesn't exist create this directory.
CFile file(_T("Version/FileList.cfg"),CFile::modeWrite|CFile::typeBinary|CFile::modeCreate);//下载服务器版本到本地
file.Write(pbuff,strLength);
file.Flush();
file.Close();
//==============================读取config文件================================ 
//-------------------------------read-server-------------------------------------
    const char* chName;
MeXmlDocument xSMeXml;
    if ( !xSMeXml.LoadFile("Version/FileList.cfg", 1 ) )
    { 
AfxMessageBox(_T("读取FileList失败"));
return ; 
}
    MeXmlElement* pSRoot = xSMeXml.FirstChildElement( "Project" );
    if ( pSRoot == NULL )
    { 
AfxMessageBox(_T("读取Project失败3"));
return ; 
}
    MeXmlElement* pCountry = pSRoot->FirstChildElement( "File" );
    if ( pCountry == NULL )
    { 
return ; 
}
//---------------------
//----------read-patch-to-download--------------------
//std::vector<CString> vecFile;
while( pCountry != NULL )
{
if ( (chName = pCountry->Attribute( "Name")) == NULL )
AfxMessageBox(_T("读取Nmae失败"));
return ; 
}
SFileName sfn;
CString strName;
strName = chName;
sfn.name = chName;
if( (chName = pCountry->Attribute( "Type")) == NULL )
{
AfxMessageBox(_T("读取Type失败"));
return;
}
CString strType;
strType = chName;
//if(strType == "Rem")
//{
//}else
//{
//
//vecFile.push_back(str);
//}
sfn.strFlag = strType;
mapFile[strName] = sfn;
       pCountry = pCountry->NextSiblingElement();
}
//
//-----------------------------------------------------
//
for(int i=0;i<vecType.size();i++)
//
{
//
if(cstrRemType == vecType[i])
//
{
CFile::Remove(cstrRootDir+vecFile[i]);//if the file doesn't exist?
//
}
//
}
delete[]pbuff;
//==================================================================================================
}

转载地址:http://kvfci.baihongyu.com/

你可能感兴趣的文章
剑指Offer 13.机器人的运动范围——DFS和BFS
查看>>
Java中GUI编程总结—AWT中的Frame容器、panel面板、布局管理
查看>>
剑指offer12.矩阵中的路径—DFS+剪枝
查看>>
Java中GUI编程总结—事件监听、TextField监听、画笔、(鼠标、窗口、键盘)监听
查看>>
Java中GUI编程总结—Swing(窗口、面板、弹窗、标签、按钮、列表、文本框)
查看>>
Java中map容器分别根据键key和值value进行排序的总结
查看>>
剑指offer面试题16. 数值的整数次方——快速幂
查看>>
剑指 Offer 39. 数组中出现次数超过一半的数字——摩尔投票法
查看>>
python中SQLite3 数据库语句使用总结——增删改查
查看>>
Java网络编程总结
查看>>
leetcode 477. 汉明距离总和——超出时间限制
查看>>
基于SSM校园二手交易市场系统——课程设计(毕业设计)
查看>>
leetcode 1882.使用服务器处理任务——优先队列
查看>>
leetcode 523.连续的子数组的和——前缀和+哈希表
查看>>
Java中的set的toArray()转成的数组如何进行接收
查看>>
剑指offer 43 1~n整数中1出现的次数
查看>>
基于SSM的图书馆管理系统——计算机类专业课程设计(毕业设计)
查看>>
leetcode 1239. 串联字符串的最大长度——回溯+位运算
查看>>
基于SSH在线考试系统(计算机专业认证考试)——计算机类专业课程设计(毕业设计)
查看>>
Springboot的仓库管理系统——计算机类专业课程设计(毕业设计)
查看>>