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

📄 filetrandlg.cpp

📁 本人买的<<VC++项目开发实例>>源代码配套光盘.
💻 CPP
字号:
// FileTranDlg.cpp : implementation file
//

#include "stdafx.h"
#include "netmsg.h"
#include "FileTranDlg.h"
#include "WorkSocket.h"
#include "NetMsgDlg.h"		//for main window CNetMsgDlg
#include "ChatDGram.h"		//for class CChatDGram
#include "ChatDlg.h"		//for message WM_CHAT_MSG

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

/////////////////////////////////////////////////////////////////////////////
// CFileTranDlg dialog

//##ModelId=3E431B0A021D
short CFileTranDlg::shortFilePort=0;
//##ModelId=3E431B0A02F2
CFileTranDlg::CFileTranDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CFileTranDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CFileTranDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


//##ModelId=3E431B0A02FB
void CFileTranDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFileTranDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CFileTranDlg, CDialog)
	//{{AFX_MSG_MAP(CFileTranDlg)
		// NOTE: the ClassWizard will add message map macros here
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFileTranDlg message handlers

//##ModelId=3E431B0A02E8
UINT CFileTranDlg::FileService(LPVOID param)
{
	//设置计数器,如果计数器不是0, 那么就表明此服务被启动过一次。
	//这个服务只能被启动一次。
	static long nCounter = 0;
	if (nCounter) 
		return 1;
	InterlockedIncrement(&nCounter);

	TRACE("FileTrans 监听开始...\n");
	//
	// 创建一个使用file port的Server Socket
	//
	CWorkSocket svrSocket;
	BOOL bRet = svrSocket.Create(CFileTranDlg::shortFilePort);
	if (!bRet)
	{
		TRACE("File Listener Create on file port error(0x%x)\n", GetLastError());
	}
	bRet = svrSocket.Listen();
	if (!bRet)
	{
		TRACE("File Listener Create on file port error(0x%x)\n", GetLastError());
	}
	//
	// 当收到一个 WM_QUIT 的消息的时候就会退出循环。
	//
	MSG msg;
	while(!PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE))
	{
		CWorkSocket *pWorkSocket = new CWorkSocket();
		ASSERT(pWorkSocket);
		//cout << "begin accept..." << endl;
		if ( !svrSocket.Accept(*pWorkSocket))
		{
			//cout << "cancel accept..." << endl;
			TRACE("Error code = 0x%x", GetLastError());
			delete pWorkSocket;
			break;
		}
		//cout << "accepted " << pWorkSocket->m_hSocket << "." << endl;
		SOCKET hConnected = pWorkSocket->Detach();
		delete pWorkSocket;
		RECVER_PARAM *lpParam = new RECVER_PARAM;
		lpParam->hSocket = hConnected;
		AfxBeginThread(CFileTranDlg::FileRecvWorkProc, (LPVOID) lpParam);
		Sleep(0);
	}
	svrSocket.Close();
	TRACE(_T("退出文件监听线程...\n"));
	//cout << "deamon thread exit..." << endl;
	AfxEndThread(0);
	return 0;
}

//##ModelId=3E431B0A02DD
UINT CFileTranDlg::FileRecvWorkProc(LPVOID lpParam)
{
	extern CNetMsgApp theApp;
	//
	// prepare for xml
	//
	::CoInitialize(NULL);
	
	ASSERT(lpParam);

	CWorkSocket *pWorkSocket = new CWorkSocket();
	pWorkSocket->Attach(((RECVER_PARAM *)lpParam)->hSocket);
	delete lpParam;

	char buf[1024] = {0};
	//
	// 得到文件报文信息
	// 从报文中解出来文件名称。
	//
	int ret = pWorkSocket->Receive(buf, sizeof(buf) - 1);
	
	//取出来文件报文后面带的文件的内容长度
	int nHeaderLen = strlen(buf) + 1; //加上后面的 '\0'
	int nFirstBlockLen = ret - nHeaderLen;

	TRACE("Receive FileHeader %d bytes.\n", ret);
	TRACE(buf);
	TRACE("\n");

	if (0 == ret || SOCKET_ERROR == ret)
	{
		TRACE("FileRecvWorkProc exit for %ld\n", ret);
		return (-1); //exit thread
	}

	CFile file;
	try
	{
		MSXML::IXMLDOMDocumentPtr xmlDoc(__uuidof(MSXML::DOMDocument));
		xmlDoc->async = false;
		BOOL bRet = xmlDoc->loadXML(_bstr_t(buf));
		_bstr_t bstrFileName = xmlDoc->selectSingleNode("FileDiagram/FileProfile")->attributes->getNamedItem("FileName")->text;
		
		
		//
		// open the file for receive
		//
		file.Open(theApp.get_WorkDIR() + "recv\\" + (const char *)bstrFileName, CFile::modeCreate | CFile::modeWrite);
	}
	catch(_com_error &e)
	{
		file.Open("error.log", CFile::modeCreate | CFile::modeWrite | CFile::modeNoTruncate);
		_bstr_t strError = e.Description();
		file.Write((const char *)strError, strError.length());
	}

	//保存第一块内容到文件中
	file.Write(buf + nHeaderLen, nFirstBlockLen);
	MSG msg;
	while (!PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE))
	{
		memset(buf, 0, sizeof(buf));
		int ret = pWorkSocket->Receive(buf, sizeof(buf) - 1);
		TRACE("Receive %d bytes.\n", ret);
		if ( 0 == ret) //remote closed
		{
			TRACE("Remote closed.\n");
			break;
		}
		else if( SOCKET_ERROR == ret)
		{			
			TRACE("Socket error.\n");
			break;
		}
		else
		{
			file.Write(buf, ret);			
		}
	}
	pWorkSocket->Close();
	delete pWorkSocket;
	file.Close();
	::CoUninitialize();
	return 0;
}

//##ModelId=3E431B0A02D2
UINT CFileTranDlg::SendFileWorkProc(LPVOID lpParam)
{
	//
	// 1. prepare for xml
	//
	::CoInitialize(NULL);
	
	ASSERT(lpParam);

	SENDER_PARAM *pSender = (SENDER_PARAM *)lpParam;
	CString strFilePath = pSender->szFilePath;
	int nFileSize = pSender->nFileSize;
	//
	//2.取得文件名
	//
	char szDrive[_MAX_DRIVE]={0}, szDir[_MAX_DIR]={0}
			, szFName[_MAX_FNAME]={0}, szExt[_MAX_EXT]={0};		
	_splitpath((const char *)strFilePath, szDrive, szDir, szFName, szExt);
	//得到文件名
	CString strFileName = "";
	strFileName = szFName;
	strFileName += szExt;

	CWorkSocket WorkSocket;
	WorkSocket.Create();
	WorkSocket.Connect(pSender->szServer, CFileTranDlg::shortFilePort);
	delete lpParam;

	char buf[1024];
	//3.组装报文
	//
	// Get file trans header
	// extract file name from the diagram
	//
	sprintf(buf, "<FileDiagram>"
	"<FileProfile FileName=\"%s\" FileSize=\"%d\">File</FileProfile>"
	"</FileDiagram>", (const char *)strFileName, nFileSize);

	//4.发送报文
	//发送的时候要把 '\0' 也加上,为了接受的时候方便识别!!!
	int ret = WorkSocket.Send(buf, strlen(buf) + 1);
	if (0 == ret || SOCKET_ERROR == ret)
		return (-1); //exit thread

	//5.打开文件以备发送
	CFile file;
	file.Open((const char *)strFilePath, CFile::modeRead | CFile::shareDenyNone | CFile::typeBinary);
	MSG msg;
	//6.发送文件
	while (!PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE))
	{
		memset(buf, 0, sizeof(buf));
		int nCount;
		nCount = 0;
		try
		{
			nCount = file.Read(buf, sizeof(buf) - 1);
		}
		catch(CFileException &e)
		{
			e.ReportError();
		}
		catch(...)
		{
			AfxMessageBox("File error!");
		}
		int ret = WorkSocket.Send(buf, nCount);		
		if ( 0 == ret ) //remote closed
		{
			break;
		}
		else if( SOCKET_ERROR == ret)
		{
			break;
		}
		else
		{
			TRACE("文件正在传送中...\n");
		}
	}
	

	WorkSocket.Close();
	file.Close();
	::CoUninitialize();
	//7.通知系统发送完毕
	//组装聊天报文
	CNetMsgDlg *pNetMsg = (CNetMsgDlg *)AfxGetMainWnd();
	CChatDGram *pChatDGram = new CChatDGram();
	pChatDGram->m_dwNetMsgID = pNetMsg->get_SelfNetMsgID();
	pChatDGram->m_strMsg = strFilePath;
	//8. 发送消息给主窗口通知收到聊天报文。
	pNetMsg->PostMessage(WM_CHAT_MSG, 0, (LPARAM)pChatDGram);
	return 0;

}

⌨️ 快捷键说明

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