MultiThreadDownLoad

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;
//==================================================================================================
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值