📄 srvrdoc.cpp
字号:
// srvrdoc.cpp : implementation of the CServerDoc class
//
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1997 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "chatsrvr.h"
#include "srvrdoc.h"
#include "srvrvw.h"
#include "msg.h"
#include "CleanDlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CServerDoc
IMPLEMENT_DYNCREATE(CServerDoc, CDocument)
BEGIN_MESSAGE_MAP(CServerDoc, CDocument)
//{{AFX_MSG_MAP(CServerDoc)
ON_COMMAND(ID_CLEAN, OnClean)
//}}AFX_MSG_MAP
ON_UPDATE_COMMAND_UI(ID_MESSAGES, OnUpdateMessages)
ON_UPDATE_COMMAND_UI(ID_CONNECTIONS, OnUpdateConnections)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServerDoc construction/destruction
CServerDoc::CServerDoc()
{
m_pSocket = NULL;
}
CServerDoc::~CServerDoc()
{
delete m_pSocket;
}
BOOL CServerDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
m_pSocket = new CListeningSocket(this);
if (m_pSocket->Create(700))
{
if (m_pSocket->Listen())
return TRUE;
}
return FALSE;
}
void CServerDoc::DeleteContents()
{
delete m_pSocket;
m_pSocket = NULL;
CString temp;
temp="服务器已经关掉!";
m_msgList.AddTail(temp);
fromlist.AddTail("服务器");
tolist.AddTail("所有人");
seclist.AddTail("FALSE");
typelist.AddTail("-3");
clrlist.AddTail("0,136,255");
while(!m_connectionList.IsEmpty())
{
CClientSocket* pSocket = (CClientSocket*)m_connectionList.RemoveHead();
if(pSocket==NULL ) continue;
CMsg* pMsg = AssembleMsg(pSocket);
if (pMsg==NULL) continue;
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();
fromlist.RemoveAll();
tolist.RemoveAll();
seclist.RemoveAll();
typelist.RemoveAll();
clrlist.RemoveAll();
if (!m_viewList.IsEmpty())
((CEditView*)m_viewList.GetHead())->SetWindowText(_T(""));
CDocument::DeleteContents();
}
/////////////////////////////////////////////////////////////////////////////
// CServerDoc serialization
void CServerDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// CEditView contains an edit control which handles all serialization
((CEditView*)m_viewList.GetHead())->SerializeRaw(ar);
}
}
/////////////////////////////////////////////////////////////////////////////
// CServerDoc diagnostics
#ifdef _DEBUG
void CServerDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CServerDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CServerDoc Operations
void CServerDoc::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 CServerDoc::ProcessPendingAccept()
{
CClientSocket* pSocket = new CClientSocket(this);
if (m_pSocket->Accept(*pSocket))
{
pSocket->Init();
m_connectionList.AddTail(pSocket);
}
else
delete pSocket;
}
void CServerDoc::ProcessPendingRead(CClientSocket* pSocket)
{
if(pSocket!=NULL)
{
do
{
CMsg* pMsg = ReadMsg(pSocket);
if(pMsg==NULL) return;
if (pMsg->m_bClose)
{
CloseSocket(pSocket);
break;
}
}
while (!pSocket->m_pArchiveIn->IsBufferEmpty());
}
UpdateClients();
}
CMsg* CServerDoc::AssembleMsg(CClientSocket* pSocket)
{
static CMsg msg;
msg.Init();
if (pSocket->m_nMsgCount >= m_msgList.GetCount() || pSocket->m_nMsgCount <0)
return NULL;
CString temp;
for (POSITION pos1 = m_msgList.FindIndex(pSocket->m_nMsgCount); pos1 != NULL;)
{
temp = m_msgList.GetNext(pos1);
msg.m_msgList.AddTail(temp);
}
for (POSITION pos2 = fromlist.FindIndex(pSocket->m_nMsgCount); pos2 != NULL;)
{
temp = fromlist.GetNext(pos2);
msg.fromlist.AddTail(temp);
}
for (POSITION pos3 = tolist.FindIndex(pSocket->m_nMsgCount); pos3 != NULL;)
{
temp = tolist.GetNext(pos3);
msg.tolist.AddTail(temp);
}
for (POSITION pos4 = seclist.FindIndex(pSocket->m_nMsgCount); pos4!= NULL;)
{
temp = seclist.GetNext(pos4);
msg.seclist.AddTail(temp);
}
for (POSITION pos5 = typelist.FindIndex(pSocket->m_nMsgCount); pos5 != NULL;)
{
temp = typelist.GetNext(pos5);
msg.typelist.AddTail(temp);
}
for (POSITION pos7= clrlist.FindIndex(pSocket->m_nMsgCount); pos7 != NULL;)
{
temp = clrlist.GetNext(pos7);
msg.clrlist.AddTail(temp);
}
pSocket->m_nMsgCount = m_msgList.GetCount();
return &msg;
}
CMsg* CServerDoc::ReadMsg(CClientSocket* pSocket)
{
static CMsg msg;
CClientSocket* pSock;
TRY
{
pSocket->ReceiveMsg(&msg);
if(msg.type=="-1")
{
bool found=false;
for(POSITION posname=m_connectionList.GetHeadPosition();posname;)
{
pSock = (CClientSocket*)m_connectionList.GetNext(posname);
if(pSock->name==msg.from )
{
found=true;
pSocket->needdel=true;
delsocket();
return NULL;
}
}
if(found==false)
{
pSocket->name=msg.from;
Message1(msg.from);
Message1("风尘仆仆地推门而入\r\n");
}
}
if(msg.type=="-2")
{
Message1(msg.from);
Message1("静静地离开了,孤单的背影显得格外潇洒\r\n");
}
int i=atoi(msg.type);
if(i>=0 && i<=32)
{
talk(i,msg.from,msg.to,msg.m_strText);
}
m_msgList.AddTail(msg.m_strText);
typelist.AddTail(msg.type);
fromlist.AddTail(msg.from);
tolist.AddTail(msg.to);
seclist.AddTail(msg.sec);
clrlist.AddTail(msg.clr);
}
CATCH(CFileException, e)
{
CString strTemp;
if (strTemp.LoadString(IDS_READERROR))
Message(strTemp);
msg.m_bClose = TRUE;
pSocket->Abort();
}
END_CATCH
return &msg;
}
void CServerDoc::SendMsg(CClientSocket* pSocket, CMsg* pMsg)
{
TRY
{
pSocket->SendMsg(pMsg);
}
CATCH(CFileException, e)
{
pSocket->Abort();
CString strTemp;
if (strTemp.LoadString(IDS_SENDERROR))
Message(strTemp);
}
END_CATCH
}
void CServerDoc::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 CServerDoc::Message(LPCTSTR lpszMessage)
{
((CServerView*)m_viewList.GetHead())->Message(lpszMessage);
}
void CServerDoc::Message1(LPCTSTR lpszMessage)
{
((CServerView*)m_viewList.GetHead())->Message1(lpszMessage);
}
/////////////////////////////////////////////////////////////////////////////
// CServerDoc Handlers
void CServerDoc::OnUpdateMessages(CCmdUI* pCmdUI)
{
pCmdUI->Enable(TRUE);
CString strFmt;
if (strFmt.LoadString(IDS_MESSAGESFMT))
{
CString strTemp;
wsprintf(strTemp.GetBuffer(50),strFmt,m_msgList.GetCount());
strTemp.ReleaseBuffer();
pCmdUI->SetText(strTemp);
}
}
void CServerDoc::OnUpdateConnections(CCmdUI* pCmdUI)
{
pCmdUI->Enable(TRUE);
CString strFmt;
if (strFmt.LoadString(IDS_CONNECTIONSFMT))
{
CString strTemp;
wsprintf(strTemp.GetBuffer(50),strFmt,m_connectionList.GetCount());
strTemp.ReleaseBuffer();
pCmdUI->SetText(strTemp);
}
}
void CServerDoc::talk(int type2, CString from1, CString to1, CString str1)
{
CString temp,to2,first,second;
if(type2>32 || type2 <0) return;
temp.LoadString(IDS_TALK0+type2);
int i=temp.Find(",");
if(i!=-1)
{
first=temp.Left(i);
if(i!=temp.GetLength()-1)
{
second=temp.Mid(i+1);
second+=":";
}
else
{
second=":";
}
Message1(from1);
Message1(first);
Message1(to1);
Message1(second);
Message1(str1);
Message1("\r\n");
}
else
{
first=temp;
second=": ";
Message1(from1);
Message1(first);
Message1(second);
Message1(str1);
Message1("\r\n");
}
}
/*
void CServerDoc::OnCheckConns()
{
// TODO: Add your command handler code here
UINT nClosedClientSockets = 0;
POSITION pos, temp;
for(pos = m_connectionList.GetHeadPosition(); pos != NULL;)
{
temp = pos;
CClientSocket* pSock = (CClientSocket*)m_connectionList.GetNext(pos);
if (pSock->HasConnectionDropped())
{
m_connectionList.RemoveAt(temp);
pSock->Close();
delete pSock;
nClosedClientSockets++;
}
}
CHAR szMessage[150] = "";
if( nClosedClientSockets > 1 )
{
sprintf( szMessage, "%d client sockets were closed because of dropped connections!",
nClosedClientSockets );
}
else if( nClosedClientSockets == 1 )
{
sprintf( szMessage, "%d client socket was closed because of dropped connection!",
nClosedClientSockets );
}
else
{
sprintf( szMessage, "No client sockets were closed." );
}
AfxMessageBox( szMessage );
}
*/
void CServerDoc::delsocket()
{
/*
CString temp;
temp="please change name!";
m_msgList.AddTail(temp);
fromlist.AddTail("服务器");
tolist.AddTail("所有人");
seclist.AddTail("FALSE");
typelist.AddTail("-5");
clrlist.AddTail("0,136,255");
*/
CClientSocket* pSock;
POSITION pos, temp;
for(pos = m_connectionList.GetHeadPosition(); pos != NULL;)
{
temp = pos;
pSock = (CClientSocket*)m_connectionList.GetNext(pos);
if (pSock->needdel==true)
{
m_connectionList.RemoveAt(temp);
break;
}
}
if(pSock==NULL) return;
CMsg* pMsg = AssembleMsg(pSock);
pMsg->m_bClose = TRUE;
SendMsg(pSock, pMsg);
if (!pSock->IsAborted())
{
pSock->ShutDown();
BYTE Buffer[50];
while (pSock->Receive(Buffer,50) > 0);
delete pSock;
}
}
void CServerDoc::OnClean()
{
// TODO: Add your command handler code here
CCleanDlg clean;
CString name;
if(clean.DoModal()==IDOK)
{
if(clean.m_cleanname=="") return;
CClientSocket* pSock;
POSITION pos, temp,posname;
bool found=false;
for(posname=m_connectionList.GetHeadPosition();posname;)
{
pSock = (CClientSocket*)m_connectionList.GetNext(posname);
if(pSock->name==clean.m_cleanname)
found=true;
}
if(!found)
{
Message1("系统:");
Message1("不能进行'踢'操作!\r\n");
return;
}
m_msgList.AddTail("");
fromlist.AddTail(clean.m_cleanname);
tolist.AddTail("所有人");
seclist.AddTail("FALSE");
typelist.AddTail("-7");
clrlist.AddTail("255,255,255");
for(pos = m_connectionList.GetHeadPosition(); pos != NULL;)
{
temp = pos;
pSock = (CClientSocket*)m_connectionList.GetNext(pos);
CMsg* pMsg = AssembleMsg(pSock);
pMsg->m_bClose = FALSE;
SendMsg(pSock, pMsg);
}
m_msgList.AddTail("");
fromlist.AddTail(clean.m_cleanname);
tolist.AddTail("所有人");
seclist.AddTail("FALSE");
typelist.AddTail("-10");
clrlist.AddTail("255,255,255");
for(pos = m_connectionList.GetHeadPosition(); pos != NULL;)
{
temp = pos;
pSock = (CClientSocket*)m_connectionList.GetNext(pos);
if (pSock->name==clean.m_cleanname)
{
if(pSock==NULL) return;
CMsg* pMsg = AssembleMsg(pSock);
pMsg->m_bClose = TRUE;
SendMsg(pSock, pMsg);
m_connectionList.RemoveAt(temp);
if (!pSock->IsAborted())
{
pSock->ShutDown();
BYTE Buffer[50];
while (pSock->Receive(Buffer,50) > 0);
delete pSock;
}
Message1("系统:聊天室掌门人以一招'佛山无影脚',将");
Message1(clean.m_cleanname);
Message1("踢出门外\r\n");
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -