void CFtpDownloadThread::Run() { USES_CONVERSION; CInternetSession InternetSession; CFtpConnection * pFtpConn = NULL; CInternetFile * pFtpFile = NULL; CString strFtpUrl, fileDir; CFileException fileException; CFile file; UINT nFtpReadSize = 0; BYTE buffer[1024] = {0}; BOOL bIsOpenFile = FALSE; CFtpFileFind * pFtpFind = NULL; strFtpUrl.Format(_T("%s"), A2W(m_strFptURL.c_str())); try { pFtpConn = InternetSession.GetFtpConnection(strFtpUrl, m_strUsr.c_str()?NULL:m_strUsr.c_str(), m_strPwd.c_str()?NULL:m_strPwd.c_str(), m_nftpPort); } catch (CInternetException * pEx) { TCHAR sz[1024]; pEx->GetErrorMessage(sz, 1024); AfxMessageBox(sz); pEx->Delete(); m_nErrorCode = FTP_SERVER_CONNECT_FAILED; goto end; } if (pFtpConn == NULL) { m_nErrorCode = FTP_SERVER_CONNECT_FAILED; goto end; } fileDir.Format(_T("%s\\%s"), m_strSaveDir.c_str(), m_strFileName.c_str()); UINT nMode = 0; //CInternetFile不支持FTP协议的端点续传,需要自己实现。 /*if (PathFileExists(fileDir)) nMode = CFile::modeWrite; else*/ nMode = CFile::modeCreate | CFile::modeReadWrite | CFile::typeBinary; if (!file.Open(fileDir, nMode, &fileException)){ m_nErrorCode = ERR_OPEN_LOACAL_SAVE_FILE; goto end; } bIsOpenFile = TRUE; file.SeekToEnd(); m_nDownloadLen = file.GetLength(); pFtpFind = new CFtpFileFind(pFtpConn); if (!pFtpFind->FindFile(m_strFileName.c_str())) { m_nErrorCode = FTP_SERVER_FILE_OPEN_ERR; pFtpFind->Close(); delete pFtpFind; goto end; } pFtpFind->FindNextFile(); m_nFtpFileLen = pFtpFind->GetLength(); pFtpFind->Close(); delete pFtpFind; pFtpFile = pFtpConn->OpenFile(m_strFileName.c_str()); if (pFtpFile == NULL) { m_nErrorCode = FTP_SERVER_FILE_OPEN_ERR; goto end; } /*//CInternetFile不支持FTP协议的断点续传,需要自己实现。 if (m_nFtpFileLen != 0) pFtpFile->Seek(m_nDownloadLen, CInternetFile::begin);*/ while(TRUE) { if (!m_bIsStart) break; if (m_nDownloadLen >= m_nFtpFileLen) break; try { nFtpReadSize = pFtpFile->Read(buffer, sizeof(buffer)); } catch (CInternetException * pEx) { TCHAR sz[1024]; pEx->GetErrorMessage(sz, 1024); AfxMessageBox(sz); pEx->Delete(); m_nErrorCode = FTP_SERVER_CONNECT_FAILED; goto end; } if (nFtpReadSize <= 0) continue; try { file.Write(buffer, sizeof(buffer)); }catch(CFileException * pEx) { TCHAR sz[1024]; pEx->GetErrorMessage(sz, 1024); AfxMessageBox(sz); pEx->Delete(); m_nErrorCode = ERR_WRITE_LOCAL_FILE; goto end; } m_nDownloadLen += nFtpReadSize; } end: if (pFtpFile) { pFtpFile->Close(); delete pFtpFile; } if (pFtpConn) { pFtpConn->Close(); delete pFtpConn; } InternetSession.Close(); if (bIsOpenFile) file.Close(); m_bIsStart = FALSE; }
HRESULT EMB::CTxTransFile::TansferFile() { //create internet conn HRESULT hRet = E_FAIL; CFtpConnection *pFtpConnectionSrc = NULL; CFtpConnection *pFtpConnectionDes = NULL; try { CInternetSession pInetSession(NULL, 1, PRE_CONFIG_INTERNET_ACCESS); //set code page if(m_taskInfo.nCodePage == CP_UTF8) { pInetSession.SetOption(INTERNET_OPTION_CODEPAGE , CP_UTF8); } ST_FTPSITEINFO sitInfoSrc; ST_FTPSITEINFO sitInfoDes; int nFtpSrcID = -1; int nFtpDesID = -1; //find first valid ftp int iftpLoop = m_taskInfo.nSrcSiteTryStart; CFWriteLog(TEXT("start src ftp check from NO.%d"), iftpLoop); const int nSrcSitCount = m_taskInfo.vSitSrc.size(); for (size_t i = 0; i < nSrcSitCount; ++i,++iftpLoop) { iftpLoop = (iftpLoop)%nSrcSitCount; ST_FTPSITEINFO& sitRef = m_taskInfo.vSitSrc[iftpLoop]; try { pFtpConnectionSrc = pInetSession.GetFtpConnection(sitRef.strFtpIp, sitRef.strUser, sitRef.strPw, sitRef.nFtpPort, sitRef.nPassive); if (pFtpConnectionSrc) { //valid m_nCurrSrcSite = iftpLoop; sitInfoSrc = sitRef; CFWriteLog(TEXT("use SrcFtp:%s %s:%d %s/%s "), sitRef.strFtpName, sitRef.strFtpIp, sitRef.nFtpPort, sitRef.strUser, sitRef.strPw); break; } } catch ( CInternetException * e) { //ftp is not valid pFtpConnectionSrc = NULL; CFWriteLog(0, TEXT("ftp not valid, %s, %s:%d,%s:%s"),sitRef.strFtpName, sitRef.strFtpIp, sitRef.nFtpPort, sitRef.strUser, sitRef.strPw); } } if (!pFtpConnectionSrc) { CFWriteLog(0, TEXT("no valid src ftp to use, clip trans failed, logicid = %s"), m_taskInfo.strClipLogicID); return EMBERR_INVALIDFTP; } //find first valid Des Ftp iftpLoop = m_taskInfo.nDesSiteTryStart; CFWriteLog(TEXT("start des ftp check from NO.%d"), iftpLoop); const int nDesSitCount = m_taskInfo.vSitDes.size(); for (size_t i = 0; i < nDesSitCount; ++i,++iftpLoop) { iftpLoop = iftpLoop%nDesSitCount; ST_FTPSITEINFO& sitRef = m_taskInfo.vSitDes[iftpLoop]; try { pFtpConnectionDes = pInetSession.GetFtpConnection(sitRef.strFtpIp, sitRef.strUser, sitRef.strPw, sitRef.nFtpPort, sitRef.nPassive); if (pFtpConnectionDes) { //valid m_nCurrDesSite = iftpLoop; sitInfoDes = sitRef; CFWriteLog(TEXT("use DesFtp:%s %s:%d %s/%s "), sitRef.strFtpName, sitRef.strFtpIp, sitRef.nFtpPort, sitRef.strUser, sitRef.strPw); break; } } catch ( CInternetException * e) { //ftp is not valid pFtpConnectionDes = NULL; CFWriteLog(0, TEXT("ftp not valid, %s, %s:%d,%s:%s"),sitRef.strFtpName, sitRef.strFtpIp, sitRef.nFtpPort, sitRef.strUser, sitRef.strPw); } } if (!pFtpConnectionDes) { CFWriteLog(0, TEXT("no valid des ftp to use, clip trans failed, logicid = %s"), m_taskInfo.strClipLogicID); return EMBERR_INVALIDFTP; } //set file dir string szSrcDir = m_taskInfo.strSrcDir; string szDirSrcUtf8 = szSrcDir; string szDesDir = m_taskInfo.strDesDir; string szDesDirUtf8 = szDesDir; string szNameSrc = m_taskInfo.strSrcFileName; string szNameSrcUtf8 = szNameSrc; string szNameDes = m_taskInfo.strDesFileName; string szNameDesUtf8 = szNameDes; if (m_taskInfo.nCodePage == CP_UTF8) { wstring wszSrcDir = Ansi2W(szSrcDir); szDirSrcUtf8 = W2UTF8(wszSrcDir); wstring wszDesDir = Ansi2W(szDesDir); szDesDirUtf8 = W2UTF8(wszDesDir); wstring wszNameSrc = Ansi2W(szNameSrc); szNameSrcUtf8 = W2UTF8(wszNameSrc); wstring wszNameDes = Ansi2W(szNameDes); szNameDesUtf8 = W2UTF8(wszNameDes); } BOOL bSrcRet = TRUE; if (szDirSrcUtf8.size()> 0) { bSrcRet = pFtpConnectionSrc->SetCurrentDirectory(szDirSrcUtf8.c_str()); } BOOL bDesRet = TRUE; if (szDesDirUtf8.size() > 0) { bDesRet = pFtpConnectionDes->SetCurrentDirectory(szDesDirUtf8.c_str()); } ULONGLONG nSrcFileLength = 0; if (!bSrcRet || !bDesRet) { ASSERT(FALSE); CFWriteLog(0, TEXT("%s ftp path not found"), bSrcRet? szDesDir.c_str(): szSrcDir.c_str()); hRet = EMBERR_DIRACCESS; throw 1; } CFtpFileFind finder(pFtpConnectionSrc); BOOL bFind = finder.FindFile(szNameSrcUtf8.c_str()); // 查找服务器上当前目录的任意文件 if (!bFind) // 如果一个文件都找不到,结束查找 { CFWriteLog(0, TEXT("src file not found. %s"), szNameSrc.c_str()); hRet = EMBERR_NOTFOUND; throw 1; } else { finder.FindNextFile(); nSrcFileLength = finder.GetLength(); m_nCurrFileLength = nSrcFileLength; CFWriteLog(0, "src file length = %I64dByte, %I64dM", nSrcFileLength, nSrcFileLength/((ULONGLONG)(1024*1024))); /* //don't delete, use these code when actor in winxp or server 2003 if (!m_taskInfo.vSitSrc[m_nCurrSrcSite].strUncDir.IsEmpty()) { //used when actor in winxp or win2003 CString strUncFile = m_taskInfo.vSitSrc[m_nCurrSrcSite].strUncDir; strUncFile += "\\"; strUncFile += m_taskInfo.strSrcFileName; OFSTRUCT ofStruct; HFILE tHandle = NULL; tHandle =OpenFile(strUncFile, &ofStruct,OF_READ ); CFWriteLog("unc file =%s, handle = %d", strUncFile, tHandle); if (tHandle) { LARGE_INTEGER tInt1; ZeroMemory(&tInt1, sizeof(tInt1)); GetFileSizeEx((HANDLE)tHandle, &tInt1); __int64 tFileSize2 = tInt1.QuadPart; if (tFileSize2 > 0) { nSrcFileLength = tFileSize2; m_nCurrFileLength = nSrcFileLength; CFWriteLog(0, "src file changed length = %I64dByte, %I64dM", nSrcFileLength, nSrcFileLength/((ULONGLONG)(1024*1024))); } CloseHandle((HANDLE)tHandle); } }*/ } //后缀名 finder.Close(); CFtpFileFind finderDes(pFtpConnectionDes); BOOL bFindDes = finderDes.FindFile(szNameDesUtf8.c_str()); finderDes.Close(); if (bFindDes) { CFWriteLog(0, TEXT("des ftp file already existed,delete and continue. %s "), szNameDes.c_str()); if(!pFtpConnectionDes->Remove(szNameDesUtf8.c_str())) { CFWriteLog(0, TEXT("des file del failed! err =%d"), GetLastError()); hRet = EMBERR_FILEACCESS; throw 1; } } //start copy file CInternetFile* pFileSrc = NULL; CInternetFile* pFileDes = NULL; CFile* pFileLocal = NULL; CMD5CALEX* pMd5 = NULL; CString strMd5Result; //start trans try { pFileSrc =pFtpConnectionSrc->OpenFile(szNameSrcUtf8.c_str()); if (!pFileSrc) { hRet = EMBERR_FILEACCESS; CFWriteLog(0, TEXT("src ftp文件打开失败, %s"),szNameSrc.c_str()); throw 1; } pFileDes = pFtpConnectionDes->OpenFile(szNameDesUtf8.c_str(), GENERIC_WRITE); if (!pFileDes) { CFWriteLog(0, TEXT("des ftp文件打开失败, %s"), szNameDes.c_str()); throw 1; } if (m_taskInfo.bDownToLocal) { CString strLocalFile = m_taskInfo.strLocalDownDir; strLocalFile.TrimRight(TEXT("\\")); CreateDirectory(strLocalFile, NULL); strLocalFile += TEXT("\\"); strLocalFile += m_taskInfo.strLocalDownFileName; pFileLocal = new CFile; if (!pFileLocal->Open(strLocalFile, CFile::modeCreate|CFile::modeWrite, NULL)) { CFWriteLog(0, TEXT("localdown file open failed. %s"), strLocalFile); hRet = EMBERR_FILEACCESS; throw 2; } } if (m_taskInfo.bMD5Check) { pMd5 = new CMD5CALEX; pMd5->Begin(); } INT64 nFileTransed= 0; INT64 nPercent = 0; const INT64 nSleepPot = m_nMaxFtpSpeedPerExc; CFWriteLog(TEXT("trans speed limit to %.2f MB/s"), m_nMaxFtpSpeedPerExc/1024.0/1024.0); INT64 nCurrTransed = 0; UINT nCurrTick = GetTickCount(); INT64 nTransedPerSecond = 0; DWORD nTickStart = GetTickCount(); INT64 nSpeedKBPerS = 0; while(nFileTransed < nSrcFileLength) { if (m_hEventQuit && WaitForSingleObject(m_hEventQuit, 0) == WAIT_OBJECT_0) { break; } byte szbuff[FREADBUFF]; UINT nRead = pFileSrc->Read(szbuff, FREADBUFF); if (nRead > 0) { pFileDes->Write(szbuff, nRead); if (pFileLocal) { pFileLocal->Write(szbuff, nRead); } if (pMd5) { pMd5->CalBuff(szbuff, nRead); } nFileTransed += nRead; INT64 nNewPercent = nFileTransed*100/nSrcFileLength; if (nNewPercent > nPercent) { nPercent = nNewPercent; m_nPercent = nPercent == 100? 99:nPercent; } //limit speed nCurrTransed += nRead; if (nSleepPot > 0 && nCurrTransed > nSleepPot) { INT64 nTickSleep =GetTickCount() - nCurrTick; nTickSleep = nTickSleep > 1000? 0:(1000-nTickSleep); nCurrTransed = 0; nCurrTick = GetTickCount(); //limit speed if (nTickSleep > 10) { Sleep(nTickSleep); } } //calc speed nTransedPerSecond += nRead; DWORD nTickNow = GetTickCount(); if (nTickNow > nTickStart) { if (nTickNow - nTickStart >= 1000) { // nSpeedKBPerS = nTransedPerSecond*1000/((nTickNow - nTickStart)*1024); nTransedPerSecond = 0; nTickStart = nTickNow; CFWriteLog("runtimeSpeed %.2f MB/s", nSpeedKBPerS/1024.0); // TRACE("\ntask%I64d, percent%d", m_taskInfo.nTaskId, nPercent); //CFWriteLog("write %I64d, total %I64d", nSrcFileLength, nFileTransed); } } } else { if (nFileTransed == nSrcFileLength) { //task finished. hRet = S_OK; m_nPercent = 99; } else { // //CFWriteLog(0, TEXT("读取源文件失败")); CFWriteLog(0, TEXT("src file write err %s, src = %I64d, writed = %I64d"), szNameSrc.c_str(), nSrcFileLength, nFileTransed); hRet = EMBERR_FILEACCESS; } break; } } //file trans finished if (nFileTransed == nSrcFileLength) { hRet = S_OK; m_nPercent =99; TRACE("\nfile trans finished"); } if (hRet==S_OK && pMd5) { strMd5Result = pMd5->GetResult(); CFWriteLog(0, "md5value = %s",strMd5Result); if (!strMd5Result.IsEmpty()) { if (!m_taskInfo.strMD5Compare.IsEmpty()) { if (m_taskInfo.strMD5Compare.CompareNoCase(strMd5Result) != 0) { CFWriteLog(0, TEXT("md5 compare error src:%s, des:%s"), m_taskInfo.strMD5Compare, strMd5Result); hRet = EMBERR_MD5NOTMATCH; } } } else { CFWriteLog(0, TEXT("md5 calculate failed")); } } } catch (CInternetException* e) { ASSERT(FALSE); char szbuff[4096]; e->GetErrorMessage(szbuff, 4094); CFWriteLog(0, TEXT("ftp file transfer exception error! %s"), szbuff); hRet = EMBERR_INTERNET; } catch(...) { ASSERT(FALSE); CFWriteLog(0, TEXT("file transfer exception error!")); } if (pFileSrc) { pFileSrc->Close(); delete pFileSrc; } if (pFileDes) { pFileDes->Close(); delete pFileDes; } if (pFileLocal) { pFileLocal->Close(); delete pFileLocal; } if (pMd5) { delete pMd5; } } catch (CInternetException* e) { hRet = EMBERR_INTERNET; CFWriteLog(0, TEXT("network error code = %d"), e->m_dwError); } catch(...) { ASSERT(FALSE); } if (pFtpConnectionSrc!=NULL) { pFtpConnectionSrc->Close(); delete pFtpConnectionSrc; } if (pFtpConnectionDes!=NULL) { pFtpConnectionDes->Close(); delete pFtpConnectionDes; } return hRet; }