⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filetransfer.cpp

📁 类似于QQ的聊天工具,分为客户端和服务器端,有共享空间,能发布公告,可传输文件
💻 CPP
字号:
// FileTransfer.cpp: implementation of the CFileTransfer class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "NetQQ.h"
#include "FileTransfer.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFileTransfer::CFileTransfer()
{
	m_hdlLoadThread     = NULL;
	m_lpLoadThreadParam = NULL;
}

CFileTransfer::~CFileTransfer()
{

}

/////////////////////////////////////////////////////////////////////////////
//获取上传线程参数结构
_LoadThreadParam* CFileTransfer::GetLoadThreadParam()
{
	return m_lpLoadThreadParam;
}

/////////////////////////////////////////////////////////////////////////////
//上传
void CFileTransfer::UpLoadFile(CWnd* pDlg, CString strUserId, DWORD dwIp) 
{
	CFileDialog fdlg(true, NULL, NULL, 
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "所有文件(*.*)|*.*||");
	if(fdlg.DoModal() == IDCANCEL)
	{
		return;
	}

	/////////////////////////////////////////////////////////////////////////
	//上传文件线程参数结构
	m_lpLoadThreadParam = new _LoadThreadParam;
	m_lpLoadThreadParam->m_bPersonal        = m_bPersonal;
	m_lpLoadThreadParam->m_dwIp             = dwIp;
	m_lpLoadThreadParam->m_pDlg             = pDlg;
	m_lpLoadThreadParam->m_strUserId        = strUserId;
	m_lpLoadThreadParam->m_strFileName      = fdlg.GetPathName();
	
	m_hdlLoadThread = CreateThread(NULL, 0, UploadThreadPorc, 
									(LPVOID)m_lpLoadThreadParam, 0, NULL);
}

/////////////////////////////////////////////////////////////////////////////
//获取上传下载线程句柄
HANDLE CFileTransfer::GetLoadThreadHandle()
{
	return m_hdlLoadThread;
}

/////////////////////////////////////////////////////////////////////////////
//上传处理线程
DWORD WINAPI CFileTransfer::UploadThreadPorc(LPVOID lpParam)
{
	_LoadThreadParam* lp = (_LoadThreadParam*)lpParam;
	CString stcMsg0;

	/////////////////////////////////////////////////////////////////////////
	//打开文件
	CFile file;
	CFileException e;
	if(!file.Open(lp->m_strFileName, CFile::modeRead | CFile::typeBinary, &e))
	{
		char err[128];
		e.GetErrorMessage(err, 128);	

		stcMsg0 = "文件打开失败:" + CString(err);
		(lp->m_pDlg)->GetDlgItem(IDC_STC0)->SetWindowText(stcMsg0);
		delete lp; lp = NULL;
		return 0;
	}
	lp->m_pFile = &file;


	DWORD dwFileLen = file.GetLength();
	float kSize = (float)(dwFileLen / 1024);
	float mSize = kSize / 1024;
	char strSize[10];
	sprintf(strSize, "%0.2fM", mSize);

	//////////////////////////////////////
	//打包上传文件信息
	CString strBuf;
	CMsgBag mbTool;
	tagPacketParam pp;

	pp.order    = "1008";
	pp.UserId   = lp->m_strUserId;
	pp.UserName = file.GetFileName();
	pp.UserChar.Format("%d", dwFileLen);
	pp.paramNum = 3;

	mbTool.DataPackage(strBuf, &pp);
	if(lp->m_bPersonal)
	{//个人文件存储
		mbTool.SetRetStatus(CString("0002"), strBuf);
	}
	/////////////////////////////////////////////////////////////////////////
	//连接服务器
	SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
	SOCKADDR_IN addrSend;
	addrSend.sin_family           = AF_INET;
	addrSend.sin_addr.S_un.S_addr = htonl(lp->m_dwIp);
	addrSend.sin_port             = htons(8000);

	if(SOCKET_ERROR  == connect(s, (sockaddr*)&addrSend, sizeof(addrSend)))
	{
		stcMsg0 = "连接服务器出错!";
		(lp->m_pDlg)->GetDlgItem(IDC_STC0)->SetWindowText(stcMsg0);		
		closesocket(s);
		file.Close();
		delete lp; lp = NULL;
		return 0;
	}

	if(SOCKET_ERROR  == send(s, strBuf.GetBuffer(0), strBuf.GetLength() + 1, MSG_PARTIAL))
	{
		stcMsg0 = "无法上传文件 [" + file.GetFileName() + "]!";
		(lp->m_pDlg)->GetDlgItem(IDC_STC0)->SetWindowText(stcMsg0);
		
		closesocket(s);
		file.Close();
		delete lp; lp = NULL;
		return 0;
	}
	lp->m_sUploadFile = s;

	char buf[10240]="\0";
	if( 1 != recv(s, buf, 1, MSG_PARTIAL))
	{
		closesocket(s);
		file.Close();
		stcMsg0 = "无法上传文件 [" + lp->m_strFileName + "]!";
		(lp->m_pDlg)->GetDlgItem(IDC_STC0)->SetWindowText(stcMsg0);
		delete lp; lp = NULL;	
		return 0;		
	}
	
	CString stcMsg1, stcMsg6;
	if(lp->m_bPersonal)
	{
		stcMsg1 = "★您可以从服务器取回您保存的个人资料";
		stcMsg6 = "★您可以将您的个人资料上传到服务器为您保存";
	}
	else
	{
		stcMsg1 = "★您可以从共享文件中下载您所需要的资料";
		stcMsg6 = "★您可以将您的资料上传到共巷文件中与同事们一起分享";
	}

	(lp->m_pDlg)->GetDlgItem(IDC_STC1)->SetWindowText(CString("正在上传:") + file.GetFileName());
	(lp->m_pDlg)->GetDlgItem(IDC_STC4)->SetWindowText(strSize);
	(lp->m_pDlg)->GetDlgItem(IDC_STC3)->SetWindowText("/");
	
	CProgressCtrl* fprog = (CProgressCtrl*)(lp->m_pDlg)->GetDlgItem(IDC_PROGRESS);
	fprog->SetRange(0, 1000);
	fprog->SetStep(1);
	fprog->ShowWindow(true);
	(lp->m_pDlg)->GetDlgItem(IDC_STC6)->ShowWindow(false);

	int nPos = 0;
	UINT nBytesRead	= 0;
	char strSized[10], strPecent[10];
	do 
	{
		nBytesRead = file.Read(buf, sizeof(buf));
		if(SOCKET_ERROR  == send(lp->m_sUploadFile, buf, nBytesRead, MSG_PARTIAL))
		{
			stcMsg0 =	"异常原因导致上传送文件 [" + lp->m_pFile->GetFileName() + "] 失败!";

			closesocket(s);
			file.Close();

			//////////////////////////////////////////////////////
			fprog->SetPos(0);
			fprog->ShowWindow(false);
			(lp->m_pDlg)->GetDlgItem(IDC_STC6)->ShowWindow(true);

			(lp->m_pDlg)->GetDlgItem(IDC_STC0)->SetWindowText(stcMsg0);
			(lp->m_pDlg)->GetDlgItem(IDC_STC1)->SetWindowText(stcMsg1);
			(lp->m_pDlg)->GetDlgItem(IDC_STC2)->SetWindowText("");
			(lp->m_pDlg)->GetDlgItem(IDC_STC3)->SetWindowText("");
			(lp->m_pDlg)->GetDlgItem(IDC_STC4)->SetWindowText("");
			(lp->m_pDlg)->GetDlgItem(IDC_STC5)->SetWindowText("");
			(lp->m_pDlg)->GetDlgItem(IDC_STC6)->SetWindowText(stcMsg6);

			delete lp; lp = NULL;
			return 0;		
		}

		nPos += nBytesRead;
		
		//////////////////////////////////////////////////////////////
		//计算已传输大小及完成百分比
		kSize = (float)nPos / 1024;
		mSize = kSize / 1024;
		sprintf(strSized, "%0.2fM", mSize);
		sprintf(strPecent, "%0.2f%", ((float)nPos / dwFileLen) * 100);
		
		(lp->m_pDlg)->GetDlgItem(IDC_STC2)->SetWindowText(strSized);
		(lp->m_pDlg)->GetDlgItem(IDC_STC5)->SetWindowText(strPecent);
		
		///////////////////////////////////////////////////////////////
		//设置进度条
		fprog->GetPos();
		int nStep = (int)(((float)nPos / dwFileLen) * 1000);
		fprog->SetPos(nStep);
	
		/////////////////////////////
		//文件读完
		if(nBytesRead < sizeof(buf))
			break;

	} while(TRUE);
	
	stcMsg0 = "文件 [" + file.GetFileName() + "] 传送成功!";

	closesocket(s);
	file.Close();

	//////////////////////////////////////////////////////
	fprog->SetPos(0);
	fprog->ShowWindow(false);
	(lp->m_pDlg)->GetDlgItem(IDC_STC6)->ShowWindow(true);

	(lp->m_pDlg)->GetDlgItem(IDC_STC0)->SetWindowText(stcMsg0);
	(lp->m_pDlg)->GetDlgItem(IDC_STC1)->SetWindowText(stcMsg1);
	(lp->m_pDlg)->GetDlgItem(IDC_STC2)->SetWindowText("");
	(lp->m_pDlg)->GetDlgItem(IDC_STC3)->SetWindowText("");
	(lp->m_pDlg)->GetDlgItem(IDC_STC4)->SetWindowText("");
	(lp->m_pDlg)->GetDlgItem(IDC_STC5)->SetWindowText("");
	(lp->m_pDlg)->GetDlgItem(IDC_STC6)->SetWindowText(stcMsg6);

	delete lp; lp = NULL;
	return 0;
}

/////////////////////////////////////////////////////////////////////////////
//下载
void CFileTransfer::DownLoadFile(CWnd* pWnd, CString* strFileInfo, DWORD dwIp)
{
	CFileDialog fdlg(false, NULL, strFileInfo[1], 
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "所有文件(*.*)|*.*||");
	if(fdlg.DoModal() == IDCANCEL)
	{
		return;
	}

	/////////////////////////////////////////////////////////////////////////
	//下载文件线程参数结构
	m_lpLoadThreadParam = new _LoadThreadParam;
	m_lpLoadThreadParam->m_dwIp             = dwIp;
	m_lpLoadThreadParam->m_bPersonal        = m_bPersonal;
	m_lpLoadThreadParam->m_pDlg             = pWnd;
	m_lpLoadThreadParam->m_strUserId        = strFileInfo[0];
	m_lpLoadThreadParam->m_strFileName      = fdlg.GetFileName();
	m_lpLoadThreadParam->m_strFileSize      = strFileInfo[2];

	m_hdlLoadThread = CreateThread(NULL, 0, DownloadThreadProc, 
									(LPVOID)m_lpLoadThreadParam, 0, NULL);
}

//////////////////////////////////////////////////////////////////////////////
//下载处理线程
DWORD WINAPI CFileTransfer::DownloadThreadProc(LPVOID lpParam)
{
	_LoadThreadParam* lp = (_LoadThreadParam*)lpParam;
	CString stcMsg0;

	CFile file;
	CFileException e;
	if(!file.Open(lp->m_strFileName, CFile::modeReadWrite | CFile::modeCreate 
					| CFile::shareDenyWrite, &e))
	{
		char err[128];
		e.GetErrorMessage(err, 128);	
		stcMsg0 = "保存文件失败:" + CString(err);
		(lp->m_pDlg)->GetDlgItem(IDC_STC0)->SetWindowText(stcMsg0);
		delete lp; lp = NULL;
		return 0;
	}
	lp->m_pFile = &file;

	//////////////////////////////////////
	//设置下载信息包
	CString strBuf;
	CMsgBag mbTool;
	tagPacketParam pp;
	pp.order  = "1013";
	pp.SentTo =	lp->m_strUserId;
	mbTool.DataPackage(strBuf, &pp);
	
	if(lp->m_bPersonal)
	{//个人文件存储
		mbTool.SetRetStatus(CString("0002"), strBuf);
	}

	/////////////////////////////////////////////////////////////////////////
	//连接服务器
	SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
	SOCKADDR_IN addrSend;
	addrSend.sin_family           = AF_INET;
	addrSend.sin_addr.S_un.S_addr = htonl(lp->m_dwIp);
	addrSend.sin_port             = htons(8000);

	if(SOCKET_ERROR  == connect(s, (sockaddr*)&addrSend, sizeof(addrSend)))
	{
		stcMsg0 = "连接服务器出错!";
		(lp->m_pDlg)->GetDlgItem(IDC_STC0)->SetWindowText(stcMsg0);		
		closesocket(s);
		delete lp; lp = NULL;
		return 0;
	}
	send(s, strBuf, strBuf.GetLength() + 1, MSG_PARTIAL);

	char buf[10240]="\0";
	if( 1 != recv(s, buf, 1, MSG_PARTIAL))
	{
		closesocket(s);
		stcMsg0 = "无法下载文件 [" + lp->m_strFileName + "]!";
		(lp->m_pDlg)->GetDlgItem(IDC_STC0)->SetWindowText(stcMsg0);
		delete lp; lp = NULL;	
		return 0;		
	}
	lp->m_sUploadFile = s;
	
	//////////////////////////////////////////////////////////////////////////////////////////////
	CString stcMsg1, stcMsg6;
	if(lp->m_bPersonal)
	{
		stcMsg1 = "★您可以从服务器取回您保存的个人资料";
		stcMsg6 = "★您可以将您的个人资料上传到服务器为您保存";
	}
	else
	{
		stcMsg1 = "★您可以从共享文件中下载您所需要的资料";
		stcMsg6 = "★您可以将您的资料上传到共巷文件中与同事们一起分享";
	}
	(lp->m_pDlg)->GetDlgItem(IDC_STC1)->SetWindowText(CString("正在下载:") + file.GetFileName());
	(lp->m_pDlg)->GetDlgItem(IDC_STC4)->SetWindowText(lp->m_strFileSize);
	(lp->m_pDlg)->GetDlgItem(IDC_STC3)->SetWindowText("/");
	
	/////////////////////////////////////////////////////////////////////////////////////////////
	CProgressCtrl* fprog = (CProgressCtrl*)(lp->m_pDlg)->GetDlgItem(IDC_PROGRESS);
	fprog->SetRange(0, 1000);
	fprog->SetStep(1);
	fprog->ShowWindow(true);
	(lp->m_pDlg)->GetDlgItem(IDC_STC6)->ShowWindow(false);

	int nPos = 0;
	BOOL bRead = TRUE;
	char strSized[10], strPecent[10];
	while(bRead)
	{
		int nResult = recv(s, buf, sizeof(buf), MSG_PARTIAL);

		switch(nResult)
		{
			case 0:
			{
				bRead = FALSE;
				//AfxMessageBox("0");
				break;
			}

			case SOCKET_ERROR:
			{
				if (GetLastError() != WSAEWOULDBLOCK) 
				{
					//AfxMessageBox("err");
					bRead = FALSE;
				}
				break;
			}
			default:
			{
				file.Write(buf, nResult);
				nPos += nResult;
				//////////////////////////////////////////////////////////////
				//计算已传输大小及完成百分比
				float mSized = (float)nPos / 1024 / 1024;
				sprintf(strSized, "%0.2fM", mSized);

				float mSize = (float)atof(lp->m_strFileSize.GetBuffer(0));
				sprintf(strPecent, "%0.2f%", (mSized / mSize ) * 100);

				(lp->m_pDlg)->GetDlgItem(IDC_STC2)->SetWindowText(strSized);
				(lp->m_pDlg)->GetDlgItem(IDC_STC5)->SetWindowText(strPecent);
				
				///////////////////////////////////////////////////////////////
				//设置进度条
				//fprog->GetPos();
				int nStep = (int)((mSized / mSize) * 1000);
				fprog->SetPos(nStep);
			}

		}
	}

	if(lp->m_bPersonal)
	{
		stcMsg0 = "您已成功取回 [" + file.GetFileName() + "] !";
	}
	else
	{
		stcMsg0 = "文件 [" + file.GetFileName() + "] 下载成功!";
	}
	
	//////////////////////////////////////////////////////
	fprog->SetPos(0);
	fprog->ShowWindow(false);
	(lp->m_pDlg)->GetDlgItem(IDC_STC6)->ShowWindow(true);

	(lp->m_pDlg)->GetDlgItem(IDC_STC0)->SetWindowText(stcMsg0);
	(lp->m_pDlg)->GetDlgItem(IDC_STC1)->SetWindowText(stcMsg1);
	(lp->m_pDlg)->GetDlgItem(IDC_STC2)->SetWindowText("");
	(lp->m_pDlg)->GetDlgItem(IDC_STC3)->SetWindowText("");
	(lp->m_pDlg)->GetDlgItem(IDC_STC4)->SetWindowText("");
	(lp->m_pDlg)->GetDlgItem(IDC_STC5)->SetWindowText("");
	(lp->m_pDlg)->GetDlgItem(IDC_STC6)->SetWindowText(stcMsg6);

	closesocket(s);
	file.Close();
	delete lp; lp = NULL;
	return 0;
}

void CFileTransfer::SetPersonalStatus(bool bStatus)
{
	m_bPersonal = bStatus;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -