vmd_ftpclient(const char * site, const char * remotefile, const char * localfile) { CInternetSession S("Eagle FTP"); CFtpConnection *f; try { f = S.GetFtpConnection(site, "anonymous", "*****@*****.**", 21, FALSE); f->SetCurrentDirectory("/"); f->GetFile(remotefile, localfile, FALSE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 1); delete f; S.Close(); return FTP_SUCCESS; } catch (CInternetException) { printf("FTP Error!\n"); return FTP_FAILURE; } return FTP_SUCCESS; }
//启动上传文件的线程 DWORD WINAPI FtpConnecter::UploadeFile(LPVOID param) { s_bThreadRunning = TRUE;//记录上传线程已启动 FtpInfo* pFtpInfo = (FtpInfo*)param; //连接FTP服务器,并开始推送文件 static int count = 0; CString strCount; try { while (1) { if (s_bStopTask)//如果要停止任务那么就跳出 break; pushTrackInfo(L"等待下一次上传任务"); if (WaitForSingleObject(pFtpInfo->_hWaitableTimer, INFINITE) != WAIT_OBJECT_0) break; //更新本次上传的本地和远程文件夹的信息 PostMessage(AfxGetApp()->m_pMainWnd->GetSafeHwnd(), WM_UpdateRemoteFolderPath, 0, 0); PostMessage(AfxGetApp()->m_pMainWnd->GetSafeHwnd(), WM_UpdateLocalFolderPath, 0, 0); if (count == 0) { count++; pushTrackInfo(L"首次启动FTP上传线程,不做上传任务"); continue; } pushTrackInfo(L"开始上传任务"); strCount.Format(_T("开始第%d次上传任务"), ++count); pushTrackInfo(strCount); if (s_bStopTask)//如果要停止任务那么就跳出 break; CInternetSession InternetSession(_T("MR"), INTERNET_OPEN_TYPE_PRECONFIG); CFtpConnection* pFtpconnection = InternetSession.GetFtpConnection( pFtpInfo->_strFtpServerIp, pFtpInfo->_strUserName, pFtpInfo->_strUserPw, pFtpInfo->_nFtpServerPort, TRUE); CString strRemotePath = getRemoteFolderPath(); CString strLocalPath = getLocalFolderPath(); pushTrackInfo(_T("上传本地文件夹 ") + strLocalPath); pushTrackInfo(_T("到FTP服务器上 ") + strRemotePath); std::vector<CString> files; //开始上传文件 //设置ftp服务器上的路径 CString strCurDir; if (strRemotePath.GetAt(strRemotePath.GetLength()-1) != _T('/')) strRemotePath += _T('/'); int pos = strRemotePath.Find(_T('/'), 0); while (pos != -1) { strCurDir = strRemotePath.Left(pos); strRemotePath = strRemotePath.Right(strRemotePath.GetLength() - pos - 1); if (!strCurDir.IsEmpty()) { CFtpFileFind ftpff(pFtpconnection); if (!ftpff.FindFile(strCurDir))//如果找不到这个目录,那么就创建之 pFtpconnection->CreateDirectory(strCurDir); pFtpconnection->SetCurrentDirectory(strCurDir); } pos = strRemotePath.Find(_T('/'), 0); } //获得本地全部要上传的文件 if (!getAllFilesUpload(files)) s_bThreadRunning = FALSE; PostMsg2Php post2php; BOOL bPut; CString strFilePath; for (std::vector<CString>::iterator iter = files.begin(); iter != files.end(); ++iter) { strFilePath = strLocalPath + _T("\\") + *iter; pushTrackInfo(_T("开始上传 ") + strFilePath); bPut = pFtpconnection->PutFile(strFilePath, *iter); if (!bPut)//如果上传不成功那么就记录下来 { pushTrackInfo(*iter + _T(" 上传失败")); s_FileFailedUpload.push_back(*iter); s_bHasUploadFailedFile = TRUE; } else { pushTrackInfo(*iter + _T(" 上传成功")); post2php.PostResult(strFilePath, PostMsg2Php::Upload, PostMsg2Php::Suc); } } if (s_bRetryUpload && s_bHasUploadFailedFile)//如果要重试上传并且也有文件上传失败 { s_bHasUploadFailedFile = FALSE; for (std::vector<CString>::iterator iter = s_FileFailedUpload.begin(); iter != s_FileFailedUpload.end(); ++iter) { static CString str; str = _T("尝试再次上传文件 ") + strLocalPath + _T("\\") + *iter; pushTrackInfo(str); strFilePath = strLocalPath + _T("\\") + *iter; bPut = pFtpconnection->PutFile(strFilePath, *iter); if (!bPut) { pushTrackInfo(L"尝试失败 : " + strLocalPath + _T("\\") + *iter); post2php.PostResult(strFilePath, PostMsg2Php::Upload, PostMsg2Php::Failed); s_bHasUploadFailedFile = TRUE; } else { pushTrackInfo(L"尝试成功 : " + strLocalPath + _T("\\") + *iter); } } } if (pFtpconnection) { pFtpconnection->Close(); delete pFtpconnection; } strCount.Format(_T("第%d次上传任务完成,总共%d个, 成功%d个,失败%d个"), count, files.size(), files.size()-s_FileFailedUpload.size(), s_FileFailedUpload.size()); pushTrackInfo(strCount); s_FileFailedUpload.clear(); } } catch (CInternetException* pEx) { TCHAR szErr[1024]; pEx->GetErrorMessage(szErr, 1024); pushTrackInfo(_T("FTP连接失败")); pushTrackInfo(szErr); pEx->Delete(); s_bThreadRunning = FALSE; return -1; } s_bThreadRunning = FALSE; return 0; }
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; }