📄 filetrandlg.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 + -