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

📄 filetransfer.cpp

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

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

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

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

CFileTransfer::CFileTransfer()
{
	m_bFileLinstenStatus = false;
}

CFileTransfer::~CFileTransfer()
{

}

void CFileTransfer::InitFlieListenSock()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested = MAKEWORD(1, 1);
	
	err = WSAStartup(wVersionRequested, &wsaData);
	if ( err != 0 ) 
	{
		return;
	}
	
	if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) 
	{
		WSACleanup( );
		return; 
	}


	//初始化监听文件传输socket
	m_FileListenSocket = socket(AF_INET, SOCK_STREAM,IPPROTO_IP);
	
	SOCKADDR_IN addr;
	addr.sin_family           = AF_INET;
	addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addr.sin_port             = htons(8000);

	int nSize = sizeof(addr);

	bind(m_FileListenSocket, (sockaddr*)&addr, nSize);
		
	listen(m_FileListenSocket, 5);

	m_bFileLinstenStatus = true;
}

void CFileTransfer::OnAccept(CConn* cn)
{
	tagFileThreadParam* ftp;
	ftp = new tagFileThreadParam;
	ftp->m_Cn      = cn;
	ftp->m_sSocket = m_FileListenSocket;

	//启动监听线程
	HANDLE handle = CreateThread(NULL, 0, AcceptFunc, (LPVOID)ftp, 0, NULL);
	CloseHandle(handle);
}

DWORD WINAPI CFileTransfer::AcceptFunc(LPVOID lpParam)
{
	tagFileThreadParam* ftp = (tagFileThreadParam*)lpParam;
	SOCKET s = ftp->m_sSocket;

	SOCKADDR_IN client;
	int sClientLength = sizeof(client);

	ftp->m_sSocket = accept(s, (sockaddr*)&client, &sClientLength);

	HANDLE handle = CreateThread(NULL, 0, ReceiveFunc, (LPVOID)ftp, 0, NULL);
	CloseHandle(handle);

	return 0;
}



DWORD WINAPI CFileTransfer::ReceiveFunc(LPVOID lpParam)
{
	tagFileThreadParam* ftp = (tagFileThreadParam*)lpParam;
	SOCKET s = ftp->m_sSocket;
	CConn* cn = ftp->m_Cn;

	char buf[10240]="\0";

	Sleep(100);
	recv(s, buf, sizeof(buf), MSG_PARTIAL);
	
	////////////////////////////////////////////
	//拆包获取数据包信息
	CMsgBag mbTool;
	long lisPersonal = mbTool.GetRetStatus(CString(buf));
	long lOreder     = mbTool.GetOrderCode(CString(buf));

	CFile file;
	CFileStatus status;

	/////////////////////////////////////////////////////////////////////////
	//用户上传
	if(lOreder == 1008)
	{
		CString strFileInfo[3];
		mbTool.SplitDate(CString(buf), strFileInfo);

		///////////////////////////////////////////////////////////////
		//设定共享文件名(id)
		CRecs rs;
		CString sql = "select * from sharefileid";
		if(!rs.Open(cn->GetActiveConn(), (_variant_t)sql))
		{
			closesocket(s);	
			delete ftp;
			return 0;
		}

		CString fileid, strFileName;
		if(!rs.GetRs()->adoEOF)
		{
			_variant_t idvalue = rs.GetRs()->GetCollect((_variant_t)0L);
			_variant_t pathvalue = rs.GetRs()->GetCollect((_variant_t)1L);
			fileid      = (char*)(_bstr_t)idvalue;
			strFileName = (char*)(_bstr_t)pathvalue;
		}

		/////////////////////////////////////////////////////////
		//更新共享文件id
		fileid.Format("%d", atoi(fileid) + 1);
		sql = "update sharefileid set sharefileid = " + fileid;
		if(!cn->ExecuteSql((_bstr_t)sql))
		{
			closesocket(s);	
			delete ftp;
			return 0;
		}

		/////////////////////////////
		//发送接受命令
		send(s, "T", 1, MSG_PARTIAL);

		strFileName += CString("\\") + fileid;
		if(!file.Open(strFileName, CFile::modeReadWrite|CFile::modeCreate|CFile::shareDenyWrite))
		{
			closesocket(s);	
			delete ftp;
			return 0;
		}

		BOOL bRead = TRUE;
		int  nRecieve = 0;
		while(bRead)
		{
			int nResult = recv(s, buf, sizeof(buf), MSG_PARTIAL);

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

				case 1:
				{
					if(CString(buf) == CString("N"))
					{
						file.Remove(strFileName);
						return 0;
					}
					else
					{
						file.Write(buf, nResult);
						break;
					}
				}
				case SOCKET_ERROR:
				{
					if (GetLastError() != WSAEWOULDBLOCK) 
					{
						bRead = FALSE;
					}
					break;
				}
				default:
					file.Write(buf, nResult);
					nRecieve += nResult;
			}
		}
		//////////////////////////////////////////////////////
		//计算接受到文件的大小
		float nMsize = (float)nRecieve / 1024 / 1024;
		char strMsize[10];
		sprintf(strMsize, "%0.2fM", nMsize);
		
		/////////////////////////////////////////////////////
		//客户上传终止处理
		if(nRecieve < (atoi(strFileInfo[2]) - 4 * 1024))
		{
			closesocket(s);	
			file.Close();
			file.Remove(strFileName);
			delete ftp;
			return 0;
		}

		//////////////////////////////////////////////////////
		//保存上传者信息
		CTime   time    = CTime::GetCurrentTime();
		CString strTime = time.Format("20%y-%m-%d %H:%M:%S");

		sql = "insert into FileShare values(" + fileid + ",'";
		sql += strFileInfo[1] + "','" + CString(strMsize) + "','";
		sql += strFileInfo[0] + "','" + strTime;
		if(lisPersonal == 2)
		{//个人
			sql += "'," + CString("1, '") + strFileName + "')";
		}
		else
		{//共享
			sql += "'," + CString("0, '") + strFileName + "')";
		}

		if(!cn->ExecuteSql((_bstr_t)sql))
		{
			closesocket(s);	
			delete ftp;
			return 0;
		}

		closesocket(s);
		file.Close();
	}

	/////////////////////////////////////////////////////////////////////////
	//用户下载
	else if(lOreder == 1013)
	{
		CString strFileId = mbTool.GetDesUserId(CString(buf));

		CRecs rs;
		///////////////////////////////////////////////////////////////////////////
		//获取用户要下载文件的路径
		CString sql = "select * from FileShare where FileID = " + strFileId;
		if(!rs.Open(cn->GetActiveConn(), (_variant_t)sql))
		{
			closesocket(s);	
			delete ftp;
			return 0;
		}

		CString strFileName;
		if(!rs.GetRs()->adoEOF)
		{
			_variant_t pathvalue = rs.GetRs()->GetCollect((_variant_t)6L);
			strFileName = (char*)(_bstr_t)pathvalue;
		}
		else
		{
			closesocket(s);	
			delete ftp;
			return 0;
		}

		/////////////////////////////////////////////////////////////////
		//检查用户下载文件是否存在	
		if(!file.GetStatus(strFileName, status))
		{//不存在
			closesocket(s);
			delete ftp;
			return 0;
		}
	
		if(!file.Open(strFileName, CFile::modeRead | CFile::shareDenyRead 
						| CFile::typeBinary))
		{
			closesocket(s);
			delete ftp;
			return 0;
		}
		send(s, "T", 1, MSG_PARTIAL);

		UINT nBytesRead	= 0;
		UINT nTotalRead = 0;
		do 
		{
			nBytesRead = file.Read(buf, sizeof(buf));
			nTotalRead += nBytesRead;
			Sleep(5);
			if(SOCKET_ERROR  == send(s, buf, nBytesRead, MSG_PARTIAL))
			{
				if (GetLastError() != WSAEWOULDBLOCK) 
				{	
					closesocket(s);
					file.Close();
					delete ftp;
					return 0;		
				}
			}
			
			if(nTotalRead < file.GetLength())
			{
				continue;
			}/////////////////////////////
			//文件读完
			else
			{
				break;			
			}

		} while(TRUE);

		closesocket(s);
		file.Close();
		if(lisPersonal == 2)
		{
			CString sql = "delete * from FileShare where FileID =" + strFileId;
			CConn* pCn = ftp->m_Cn;
			if(pCn->ExecuteSql((_bstr_t)sql))
			{
				file.Remove(strFileName);
			}
		}
	}
	delete ftp;
	return 0;
}


SOCKET CFileTransfer::GetFlieListenSock()
{
	return m_FileListenSocket;
}


void CFileTransfer::CloseFileSock()
{
	closesocket(m_FileListenSocket);
	WSACleanup();
}

⌨️ 快捷键说明

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