用MFC CSocket类实现的网络聊天室_第1页
用MFC CSocket类实现的网络聊天室_第2页
用MFC CSocket类实现的网络聊天室_第3页
用MFC CSocket类实现的网络聊天室_第4页
用MFC CSocket类实现的网络聊天室_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

用CSocket类实现的网络聊天室一、服务器端应用程序(Ts.exe)的实现步骤1、建立“基于对话框”类型的MFC项目,项目名称Ts。按照向导进行设置,当打开“高级功能”设置页面时,勾选“Windows套接字”选项,如图所示,其他步骤采用默认值即可。2、界面控件设计。在对话框资源编辑窗口中设计如图所示界面,界面上控件的属性按照下表设置。序号控件类型ID属性值1IDC_STATICCaption监听端口号:2IDC_EDIT_PORT3IDC_BUTTON_LISTENCaption监听4IDOKCaption停止服务DisabledTrue5ID_LIST_MSGSortFalse6IDC_STATIC_NUMCaption聊天室在线人数:03、打开“MFC类向导”,按照下表设置控件在CTsDlg类中的成员变量,效果如图所示;控件ID成员变量名称类别变量类型IDC_STATIC_NUMm_strNumValueCStringIDC_EDIT_PORTm_nPortValueUINTIDC_BUTTON_LISTENm_btnListenControlCButtonIDOKm_btnCloseControlCButtonIDC_LIST_MSGm_listMsgControlCListBox4、选择菜单“项目”-“添加类”,添加一个“MFC类”:CMsg,基类选择CObject,如图所示。为CMsg添加两个成员变量:CString m_strText;/字符串成员,消息文本BOOL m_bClose;/退出聊天室标识接下来,在Msg.h文件中添加DECLARE_SERIAL宏,在Msg.cpp文件中添加IMPLEMENT_SERIAL宏;最后,使用MFC类向导添加虚函数Serialize(),如图所示。CMsg类的代码如下:/ Msg.h#pragma once/ CMsg 命令目标class CMsg : public CObjectDECLARE_SERIAL(CMsg)public:CMsg();virtual CMsg();public:CString m_strText;/字符串成员,消息文本BOOL m_bClose;/退出聊天室标识virtual void Serialize(CArchive& ar);/ Msg.cpp : 实现?文?件t#include stdafx.h#include Ts.h#include Msg.h/ CMsgIMPLEMENT_SERIAL(CMsg,CObject,0)CMsg:CMsg()CMsg:CMsg()void CMsg:Serialize(CArchive& ar)if (ar.IsStoring()/ storing codearm_strTextm_strTextm_bClose;5、从CSocket类派生两个套接字类,一个名为CLSocket,专用于监听客户机端的连接请求;另一个名为CCSocket,用于与客户机建立连接并交换数据。操作步骤为:选择菜单“项目”-“添加类”,在弹出的对话框中选择“MFC类”项,单击“添加”按钮;然后在弹出的“MFC添加类向导”窗口中输入类名,并选择基类为CSocket,如图所示。6、使用“MFC类向导”为CLSocket类添加OnAccept事件处理函数,操作如图所示。7、使用“MFC类向导”为CCSocket类添加OnReceive事件处理函数,操作如下图所示。8、分别为CLSocket和CCSocket类添加一个指向对话框类的指针变量:CTsDlg* m_pDlg;为避免对话框类与套接字类交叉引用,在类的定义前添加 class CTsDlg;修改CLSocket和CCSocket类的构造函数,添加一个CTsDlg*类型的参数。如图所示。 在LSocket.cpp中添加头文件的引用,并完成CLSocket类构造函数的修改:#include TsDlg.hCLSocket:CLSocket(CTsDlg *pDlg)this-m_pDlg=pDlg;同样,在CSocket.cpp中添加头文件的引用,并完成CCSocket类构造函数的修改:#include TsDlg.hCCSocket:CCSocket(CTsDlg *pDlg)this-m_pDlg=pDlg;9、为CCSocket类添加成员变量和成员函数的定义(CSocket.h)。成员变量:CSocketFile* m_pFile;/CSocketFile对象指针变量CArchive* m_pArIn;/用于输出的CArchive对象指针CArchive* m_pArOut;/用于输出的CArchive对象指针成员函数:void ReceiveMsg(CMsg* pMsg);/接收消息void SendMsg(CMsg* pMsg);/发送消息void Initialize();/初始化在CSocket.cpp中,实现这三个成员函数,并修改CCSocket类的析构函数:void CCSocket:Initialize()m_pFile=new CSocketFile(this,TRUE);m_pArIn=new CArchive(m_pFile,CArchive:load);m_pArOut=new CArchive(m_pFile,CArchive:store);void CCSocket:SendMsg(CMsg *pMsg)if(m_pArOut!=NULL)pMsg-Serialize(*m_pArOut);m_pArOut-Flush();void CCSocket:ReceiveMsg(CMsg *pMsg)pMsg-Serialize(*m_pArIn);CCSocket:CCSocket()m_pDlg=NULL;if(m_pArOut!=NULL)m_pArOut-Close();delete m_pArOut;m_pArOut=NULL;if(m_pArIn!=NULL)m_pArIn-Close();delete m_pArIn;m_pArIn=NULL;if(m_pFile!=NULL)m_pFile-Close();delete m_pFile;m_pFile=NULL;10、在TsDlg.h文件(CTsDlg类的定义文件)中添加下面两个文件的引用:#include CSocket.h#include LSocket.h并添加成员变量:CLSocket* m_pLSocket;/监听套接字指针 CPtrList m_connList;/连接列表 和成员函数的声明:void backClient(CMsg* pMsg); /向聊天室所有客户机转发消息 void OnReceive(CCSocket* pSocket);/获取客户机消息 void OnAccept();/接受连接请求 在TsDlg.cpp中,实现这三个成员函数:void CTsDlg:OnAccept()CCSocket *pSocket=new CCSocket(this);if(m_pLSocket-Accept(*pSocket)pSocket-Initialize();m_connList.AddTail(pSocket);CString strTemp;strTemp.Format(L在线人数:%d,m_connList.GetCount();m_strNum=strTemp;UpdateData(FALSE);elsedelete pSocket;void CTsDlg:OnReceive(CCSocket *pSocket)static CMsg msg;dopSocket-ReceiveMsg(&msg);m_listMsg.AddString(msg.m_strText);backClient(&msg);if(msg.m_bClose)pSocket-Close();POSITION pos,temp;CCSocket *pTemp;for(pos=m_connList.GetHeadPosition();pos!=NULL;)temp=pos;pTemp=(CCSocket*)m_connList.GetNext(pos);if(pTemp=pSocket)m_connList.RemoveAt(temp);CString strTemp;strTemp.Format(L在线人数:%d,m_connList.GetCount();m_strNum=strTemp;UpdateData(FALSE);delete pSocket;break;while(!pSocket-m_pArIn-IsBufferEmpty();void CTsDlg:backClient(CMsg *pMsg)CCSocket *pSocket;for(POSITION pos=m_connList.GetHeadPosition();pos!=NULL;)pSocket=(CCSocket*)m_connList.GetNext(pos);pSocket-SendMsg(pMsg);11、完成CLSocket类的OnAccept()函数的代码(第6步添加的虚函数):void CLSocket:OnAccept(int nErrorCode)CSocket:OnAccept(nErrorCode);if(m_pDlg!=NULL)m_pDlg-OnAccept();完成CCSocket类的OnAccept()函数的代码(第7步添加的虚函数):void CCSocket:OnReceive(int nErrorCode)CSocket:OnReceive(nErrorCode);m_pDlg-OnReceive(this);12、为对话框CTsDlg的“监听”和“停止服务”两个按钮添加消息响应函数。(方法可以在对话框资源编辑窗口双击对应按钮,或使用类向导)void CTsDlg:OnBnClickedButtonListen() / TODO: Add your control notification handler code hereUpdateData(TRUE);m_pLSocket=new CLSocket(this);if(!m_pLSocket-Create(m_nPort)delete m_pLSocket;m_pLSocket=NULL;AfxMessageBox(L创建监听套接字错误);return;if(!m_pLSocket-Listen()delete m_pLSocket;m_pLSocket=NULL;AfxMessageBox(L启动监听错误);return;GetDlgItem(IDC_EDIT_PORT)-EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_LISTEN)-EnableWindow(FALSE);GetDlgItem(IDOK)-EnableWindow(TRUE);void CTsDlg:OnBnClickedOk() / TODO: Add your control notification handler code hereCMsg msg;msg.m_strText=L服务器终止服务;delete m_pLSocket;m_pLSocket=NULL;CCSocket* pSocket;while(!m_connList.IsEmpty()pSocket=(CCSocket*)m_connList.RemoveHead();pSocket-SendMsg(&msg);delete pSocket;while(m_listMsg.GetCount()!=0)m_listMsg.DeleteString(0);GetDlgItem(IDC_EDIT_PORT)-EnableWindow(TRUE);GetDlgItem(IDC_BUTTON_LISTEN)-EnableWindow(TRUE);GetDlgItem(IDOK)-EnableWindow(FALSE);13、最后,在CTsdlg类的OninitDialog()函数中添加如下初始化代码:m_nPort=8000;UpdateData(FALSE);GetDlgItem(IDOK)-EnableWindow(FALSE);效果如下:二、客户端应用程序(Tc.exe)的实现步骤1、建立“基于对话框”类型的MFC项目,项目名称Tc。按照向导进行设置,当打开“高级功能”设置页面时,勾选“Windows套接字”选项,如图所示,其他步骤采用默认值即可。2、界面控件设计。在对话框资源编辑窗口中设计如图所示界面,界面上控件的属性按照下表设置。序号控件类型ID属性值1IDC_EDIT_CNAME2IDC_EDIT_SNAME3IDC_EDIT_PORT4IDC_EDIT_MSG5ID_LIST_MSGSortFalse6IDC_BUTTON_CLOSECaption退出7IDC_BUTTON_CONNCaption连接8IDOKCaption发送9IDC_STATICCaption客户名:10IDC_STATICCaption服务器名:11IDC_STATICCaption端口:12IDC_STATICCaption消息:3、打开“MFC类向导”,按照下表设置控件在CTsDlg类中的成员变量,效果如图所示;控件ID成员变量名称类别变量类型IDC_EDIT_CNAMEm_strCNameValueCStringIDC_EDIT_SNAMEm_strSNameValueCStringIDC_EDIT_PORTm_nPortValueUINTIDC_EDIT_MSGm_strMsgValueCStringIDC_BUTTON_CONNm_btnConnControlCButtonIDOKm_SendControlCButtonID_BUTTON_CLOSEm_btnCloseControlCButtonIDC_LIST_MSGm_listMsgControlCListBox4、创建CMsg类。方法同服务器端应用程序(Ts.exe)步骤4。也可以直接将服务器端应用程序的CMsg类添加到当前工程中,方法为:1)首先将Msg.h和Msg.cpp两个文件复制到当前工程目录下;2)然后选择菜单“项目”-“添加现有项”,在弹出的对话框中选中这两个文件,单击“添加”按钮,如图所示;3)这时在类视图中会出现CMsg类,如图所示。4)打开CMsg类的实现文件(Msg.cpp),将其中的头文件引用:#include Ts.h改为:#include Tc.h5、从CSocket类派生一个套接字类CCSocket,用于与客户机建立连接并交换数据。如图所示:6、使用类向导,为CCSocket类添加OnReceive事件处理函数,如图所示。8、为CCSocket类添加一个指向对话框类的指针变量:CTcDlg* m_pDlg;为避免对话框类与套接字类交叉引用,在类的定义前添加 class CTcDlg;修改CCSocket类的构造函数,添加一个CTcDlg*类型的参数。如图所示。 在CSocket.cpp中添加头文件的引用,并完成CCSocket类构造函数的修改:#include TcDlg.hCCSocket:CCSocket(CTcDlg* pDlg)m_pDlg=pDlg;9、在TcDlg.h文件(CTsDlg类的定义文件)中添加下面的头文件引用:#include CSocket.h并添加成员变量:CCSocket* m_pSocket;/套接字对象指针 CSocketFile *m_pFile;/CSoketFile对象指针 CArchive *m_pArchiveIn;/用于输入的CArchive对象 CArchive *m_pArchiveOut;/用于输出的CArchive对象 和成员函数的声明:void OnReceive();/接收信息 void ReceiveMsg();/接收服务器发送来的消息 void SendMsg(CString& strText,bool st);/向服务器发送消息 在TcDlg.cpp中,添加对Msg.h文件的引用和实现这三个成员函数:#include Msg.hvoid CTcDlg:OnReceive()doReceiveMsg();if(m_pSocket=NULL)return;while(!m_pArchiveIn-IsBufferEmpty();void CTcDlg:ReceiveMsg()CMsg msg;TRYmsg.Serialize(*m_pArchiveIn);m_listMsg.AddString(msg.m_strText);CATCH(CFileException,e)CString strTemp;strTemp=L服t务?器重?置?连?接!?连?接关?闭?;m_listMsg.AddString(strTemp);msg.m_bClose=TRUE;m_pArchiveOut-Abort();delete m_pArchiveIn;m_pArchiveIn=NULL;delete m_pArchiveOut;m_pArchiveOut=NULL;delete m_pFile;m_pFile=NULL;delete m_pSocket;m_pSocket=NULL;END_CATCHvoid CTcDlg:SendMsg(CString& strText,bool st)if(m_pArchiveOut!=NULL)CMsg msg;msg.m_strText=strText;msg.m_bClose=st;msg.Serialize(*m_pArchiveOut);m_pArchiveOut-Flush();10、为对话框CTcDlg的“退出”、“连接”和“发送”三个按钮添加消息响应函数。(方法可以在对话框资源编辑窗口双击对应按钮,或使用类向导)void CTcDlg:OnBnClickedButtonConn() / TODO: Add your control notification handler code hereUpdateData(TRUE);m_pSocket=new CCSocket(this);if(!m_pSocket-Create()delete m_pSocket;m_pSocket=NULL;AfxMessageBox(L套接字创建错误);return;if(!m_pSocket-Connect(m_strSName,m_nPort)delete m_pSocket;m_pSocket=NULL;AfxMessageBox(L无法连接到服务器);return;m_pFile=new CSocketFile(m_pSocket);m_pArchiveIn=new CArchive(m_pFile,CArchive:load);m_pArchiveOut=new CArchive(m_pFile,CArchive:store);UpdateData(TRUE);CString strTemp;strTemp=m_strCName+L:进入聊天室;SendMsg(strTemp,FALSE);GetDlgItem(IDC_EDIT_MSG)-EnableWindow(TRUE);GetDlgItem(IDOK)-EnableWindow(TRUE);GetDlgItem(IDC_BUTTON_CLOSE)-EnableWindow(TRUE);GetDlgItem(IDC_EDIT_CNAME)-EnableWindow(FALSE);GetDlgItem(IDC_EDIT_SNAME)-EnableWindow(FALSE);GetDlgItem(IDC_EDIT_PORT)-EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_CONN)-EnableWindow(FALSE);void CTcDlg:OnBnClickedButtonClose() / TODO: Add your control notification handler code hereCString strTemp;strTemp=m_strCName+L离开聊天室;SendMsg(strTemp,TRUE);delete m_pArchiveOut;m_pArchiveOut=NULL;delete m_pArchiveIn;m_pArchiveIn=NULL;delete m_pFile;m_pFile=NULL;m_pSocket-Close();delete m_pSocket;m_pSocket=NULL;while(m_listMsg.GetCount()!=0)m_listMsg.DeleteString(0);GetDlgItem(IDC_EDIT_MSG)-EnableWindow(FALSE);GetDlgItem(IDOK)-EnableWindow(FALSE);GetDlgItem(IDC_BUTTON_CLOSE)-EnableWindow(FALSE);GetDlgItem(IDC_EDIT_CNAME)-EnableWindow(TRUE);GetDlgItem(IDC_EDIT_SNAME)-EnableWindow(TRUE);GetDlgItem(IDC_EDIT_PORT)-EnableWindow(TRUE);GetDlgItem(IDC_BUTTON_CONN)-EnableWindow(TRUE);11、打开类向导,为T

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论