Exemple #1
0
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;
}
Exemple #3
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;
}