// 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 "message.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)
//ON_UPDATE_COMMAND_UI(ID_TEST,On_My)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServerDoc construction/destruction
CServerDoc::CServerDoc()
{
m_pSocket = NULL;
m_lCount = 0;
}
CServerDoc::~CServerDoc()
{
if(m_pSocket != NULL)
delete m_pSocket;
m_pSocket = NULL;
}
//
//这里开始打开该端口的网络服务,等待客户的连接
//
BOOL CServerDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
m_pSocket = new CListeningSocket(this);
if (m_pSocket->Create(PORT)){
if (m_pSocket->Listen())
return TRUE;
}
return FALSE;
}
//该函数在有客户连接时关闭服务器时调用
void CServerDoc::DeleteContents()
{
delete m_pSocket;
m_pSocket = NULL;
CString temp;
temp="服务器已经关掉!";
CMessage* pMsg = new CMessage;
while(!m_connectionList.IsEmpty())
{
CClientSocket* pSocket = (CClientSocket*)m_connectionList.RemoveHead();
if(pSocket==NULL ) continue;
if (pMsg == NULL) continue;
pMsg->m_bClose = TRUE;
pMsg->from = pSocket->name;
pMsg->m_strText = _TEXT("服务器已关闭");
pMsg->to = _TEXT("所有人");
pMsg->type = -3;
SendMsg(pSocket, pMsg);
if(!pSocket->IsAborted())
{
pSocket->ShutDown();
BYTE Buffer[50];
while (pSocket->Receive(Buffer,50) > 0);
delete pSocket;
}
}
delete pMsg;
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()
{
CMessage* pMsg = AssembleMsg(NULL);
if(pMsg->type >= 0)
m_lCount ++;
for(POSITION pos = m_connectionList.GetHeadPosition(); pos != NULL;){
CClientSocket* pSocket = (CClientSocket*)m_connectionList.GetNext(pos);
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{
CMessage* pMsg = ReadMsg(pSocket);
if(pMsg == NULL) return;
if (pMsg->m_bClose)
{
CloseSocket(pSocket);
pMsg->m_bClose = FALSE;
break;
}
if(pMsg->type == -1){
UpdateList(pSocket);
}
}
while (!pSocket->m_pArchiveIn->IsBufferEmpty());
}
UpdateClients();
}
CMessage* CServerDoc::AssembleMsg(CClientSocket* pSocket)
{
static CMessage msg;
CMessage* tmp;
tmp = m_lsMsg.RemoveHead();
if(tmp != NULL)
memcpy(&msg, tmp, sizeof(CMessage));
return &msg;
}
CMessage* CServerDoc::ReadMsg(CClientSocket* pSocket)
{
static CMessage 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;
pSocket->image = msg.image;
Message1(msg.from);
Message1("风尘仆仆地推门而入\r\n");
}
}
if(msg.type == -2)
{
Message1(msg.from);
Message1("静静地离开了,孤单的背影显得格外潇洒\r\n");
}
int i = msg.type;
if(i >= 0 && i <= 32){
talk(i,msg.from,msg.to,msg.m_strText);
}
if(i >= -2 && i <= 32){
m_lsMsg.AddTail(&msg);
}
}
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, CMessage* 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_lCount);
strTemp.ReleaseBuffer();
pCmdUI->SetText(strTemp);
}
}
void CServerDoc::OnUpdateConnections(CCmdUI* pCmdUI)
{
pCmdUI->Enable(FALSE);//我终于明白了
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::DelSocket()
{
CClientSocket* pSock;
POSITION pos, temp;
for(pos = m_connection
QQ聊天工具实现,包含客户端服务器程序,使用MFC
5星 · 超过95%的资源 需积分: 9 111 浏览量
2009-05-22
09:02:55
上传
评论 7
收藏 7.15MB RAR 举报
libaojun2
- 粉丝: 0
- 资源: 1
最新资源
- 毕业设计基于STM32的测量温度与压力的数据处理设计C语言完整源码+论文.zip
- 基于MATLAB的PCA算法人脸识别项目源码+GUI界面+说明文档.zip
- 基于STM32的测量温度与压力的数据处理设计源码+论文(毕业设计).zip
- Vision Transformer 网络对不同氨气氧气浓度轨迹RAS 图像数据集的分类,包含训练权重和数据集、迁移学习
- 基于C51带字库LCD12864(ST7920)的keil工程源码,只支持8位并口通讯(不支持串口),可显示中文.zip
- 基于SI4463射频模块433MD-SMA无线模块软硬件技术资料及(SI4463)IC技术资料文档.zip
- (GPS+北斗+GSM)HLK-GS2503模块软硬件开发资料包硬件参考设计(原理图PCB)+技术文档资料.zip
- 基于BERT+Biaffine结构的关系抽取模型源码+文档说明.zip
- 利用c语言编写的冒泡排序代码
- 基于Ansoft-HFSS知识总结hfss中文教程HFSS培训教材等技术资料合集(50个).zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
- 4
前往页