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

📄 chatsrvrdoc.cpp

📁 《Visual C++.NET MFC类库应用详解》程序实例
💻 CPP
字号:
// ChatSrvrDoc.cpp :  CChatSrvrDoc 类的实现
//

#include "stdafx.h"
#include "ChatSrvr.h"
#include "ChatSrvrDoc.h"
#include "Msg.h"
#include "ChatSrvrView.h"
#include "PortDialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CChatSrvrDoc

IMPLEMENT_DYNCREATE(CChatSrvrDoc, CDocument)

BEGIN_MESSAGE_MAP(CChatSrvrDoc, CDocument)
END_MESSAGE_MAP()


// CChatSrvrDoc 构造/销毁

CChatSrvrDoc::CChatSrvrDoc()
{
	m_pSocket = NULL;
}

CChatSrvrDoc::~CChatSrvrDoc()
{
	delete m_pSocket;
}


BOOL CChatSrvrDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	CPortDialog portDlg;

	if (portDlg.DoModal() == IDOK)
	{
		m_pSocket = new CListeningSocket(this);
		if (m_pSocket->Create(portDlg.m_nPort+700))
		{
			if (m_pSocket->Listen())
				return TRUE;
		}
	}
	return FALSE;
}


// CChatSrvrDoc 序列化

void CChatSrvrDoc::Serialize(CArchive& ar)
{
	// CEditView 包含一个处理所有序列化的编辑控件
	reinterpret_cast<CEditView*>(m_viewList.GetHead())->SerializeRaw(ar);
}


// CChatSrvrDoc 诊断

#ifdef _DEBUG
void CChatSrvrDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CChatSrvrDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG


// CChatSrvrDoc 命令

void CChatSrvrDoc::DeleteContents()
{
	// TODO: 在此添加专用代码和/或调用基类
	delete m_pSocket;
	m_pSocket = NULL;

	CString temp;
	if (temp.LoadString(IDS_SERVERSHUTDOWN))
		m_msgList.AddTail(temp);

	while(!m_connectionList.IsEmpty())
	{
		CClientSocket* pSocket = (CClientSocket*)m_connectionList.RemoveHead();
		CMsg* pMsg = AssembleMsg(pSocket);
		pMsg->m_bClose = TRUE;

		SendMsg(pSocket, pMsg);

		if (!pSocket->IsAborted())
		{
			pSocket->ShutDown();

			BYTE Buffer[50];

			while (pSocket->Receive(Buffer,50) > 0);

			delete pSocket;
		}
	}

	m_msgList.RemoveAll();

	if (!m_viewList.IsEmpty())
		((CEditView*)m_viewList.GetHead())->SetWindowText(_T(""));

	CDocument::DeleteContents();
}

void CChatSrvrDoc::UpdateClients()
{
	for(POSITION pos = m_connectionList.GetHeadPosition(); pos != NULL;)
	{
		CClientSocket* pSocket = (CClientSocket*)m_connectionList.GetNext(pos);
		CMsg* pMsg = AssembleMsg(pSocket);

		if (pMsg != NULL)
			SendMsg(pSocket, pMsg);
	}
}

void CChatSrvrDoc::ProcessPendingAccept()
{
	CClientSocket* pSocket = new CClientSocket(this);

	if (m_pSocket->Accept(*pSocket))
	{
		pSocket->Init();
		m_connectionList.AddTail(pSocket);
	}
	else
		delete pSocket;
}

void CChatSrvrDoc::ProcessPendingRead(CClientSocket* pSocket)
{
	do
	{
		CMsg* pMsg = ReadMsg(pSocket);

		if (pMsg->m_bClose)
		{
			CloseSocket(pSocket);
			break;
		}
	}
	while (!pSocket->m_pArchiveIn->IsBufferEmpty());

	UpdateClients();
}

CMsg* CChatSrvrDoc::AssembleMsg(CClientSocket* pSocket)
{
	static CMsg msg;

	msg.Init();

	if (pSocket->m_nMsgCount >= m_msgList.GetCount())
		return NULL;

	for (POSITION pos1 = m_msgList.FindIndex(pSocket->m_nMsgCount); pos1 != NULL;)
	{
		CString temp = m_msgList.GetNext(pos1);
		msg.m_msgList.AddTail(temp);
	}
	pSocket->m_nMsgCount = m_msgList.GetCount();
	return &msg;
}

CMsg* CChatSrvrDoc::ReadMsg(CClientSocket* pSocket)
{
	static CMsg msg;

	try
	{
		pSocket->ReceiveMsg(&msg);

		Message(msg.m_strText);

		m_msgList.AddTail(msg.m_strText);
	}
	catch(CFileException e)
	{
		CString strTemp;
		if (strTemp.LoadString(IDS_READERROR))
			Message(strTemp);

		msg.m_bClose = TRUE;
		pSocket->Abort();
	}

	return &msg;
}

void CChatSrvrDoc::SendMsg(CClientSocket* pSocket, CMsg* pMsg)
{
	try
	{
		pSocket->SendMsg(pMsg);
	}
	catch(CFileException e)
	{
		pSocket->Abort();

		CString strTemp;
		if (strTemp.LoadString(IDS_SENDERROR))
			Message(strTemp);
	}
}

void CChatSrvrDoc::CloseSocket(CClientSocket* pSocket)
{
	pSocket->Close();

	POSITION pos,temp;
	for(pos = m_connectionList.GetHeadPosition(); pos != NULL;)
	{
		temp = pos;
		CClientSocket* pSock = (CClientSocket*)m_connectionList.GetNext(pos);
		if (pSock == pSocket)
		{
			m_connectionList.RemoveAt(temp);
			break;
		}
	}

	delete pSocket;
}

void CChatSrvrDoc::Message(LPCTSTR lpszMessage)
{
	((CChatSrvrView*)m_viewList.GetHead())->Message(lpszMessage);
}

⌨️ 快捷键说明

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