版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
./用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添加两个成员变量: CStringm_strText;//字符串成员,消息文本
BOOLm_bClose; //退出聊天室标识
接下来,在Msg.h文件中添加DECLARE_SERIAL宏,在Msg.cpp文件中添加IMPLEMENT_SERIAL宏;最后,使用MFC类向导添加虚函数Serialize<>,如图所示。CMsg类的代码如下://Msg.h#pragmaonce//CMsg命令目标classCMsg:publicCObject{ DECLARE_SERIAL<CMsg>public: CMsg<>;virtual~CMsg<>;public: CStringm_strText;//字符串成员,消息文本 BOOLm_bClose; //退出聊天室标识virtualvoidSerialize<CArchive&ar>;};//Msg.cpp:实º¦Ì现?文?件t#include"stdafx.h"#include"Ts.h"#include"Msg.h"//CMsgIMPLEMENT_SERIAL<CMsg,CObject,0>CMsg::CMsg<>{}CMsg::~CMsg<>{}voidCMsg::Serialize<CArchive&ar>{if<ar.IsStoring<>> { //storingcode ar<<m_strText<<m_bClose; }else { //loadingcode ar>>m_strText>>m_bClose; }}5、从CSocket类派生两个套接字类,一个名为CLSocket,专用于监听客户机端的连接请求;另一个名为CCSocket,用于与客户机建立连接并交换数据。操作步骤为:选择菜单"项目"->"添加类",在弹出的对话框中选择"MFC类"项,单击"添加"按钮;然后在弹出的"MFC添加类向导"窗口中输入类名,并选择基类为CSocket,如图所示。6、使用"MFC类向导"为CLSocket类添加OnAccept事件处理函数,操作如图所示。7、使用"MFC类向导"为CCSocket类添加OnReceive事件处理函数,操作如下图所示。8、分别为CLSocket和CCSocket类添加一个指向对话框类的指针变量:
CTsDlg*m_pDlg;
为避免对话框类与套接字类交叉引用,在类的定义前添加
classCTsDlg;
修改CLSocket和CCSocket类的构造函数,添加一个CTsDlg*类型的参数。如图所示。
在LSocket.cpp中添加头文件的引用,并完成CLSocket类构造函数的修改:#include"TsDlg.h"CLSocket::CLSocket<CTsDlg*pDlg>{this->m_pDlg=pDlg;}同样,在CSocket.cpp中添加头文件的引用,并完成CCSocket类构造函数的修改:#include"TsDlg.h"CCSocket::CCSocket<CTsDlg*pDlg>{this->m_pDlg=pDlg;}9、为CCSocket类添加成员变量和成员函数的定义〔CSocket.h。
成员变量:
CSocketFile*m_pFile; //CSocketFile对象指针变量
CArchive*m_pArIn; //用于输出的CArchive对象指针
CArchive*m_pArOut; //用于输出的CArchive对象指针
成员函数:
voidReceiveMsg<CMsg*pMsg>;//接收消息
voidSendMsg<CMsg*pMsg>; //发送消息
voidInitialize<>; //初始化
在CSocket.cpp中,实现这三个成员函数,并修改CCSocket类的析构函数:voidCCSocket::Initialize<>{ m_pFile=newCSocketFile<this,TRUE>; m_pArIn=newCArchive<m_pFile,CArchive::load>; m_pArOut=newCArchive<m_pFile,CArchive::store>;}voidCCSocket::SendMsg<CMsg*pMsg>{ if<m_pArOut!=NULL> { pMsg->Serialize<*m_pArOut>; m_pArOut->Flush<>; }}voidCCSocket::ReceiveMsg<CMsg*pMsg>{ pMsg->Serialize<*m_pArIn>;}CCSocket::~CCSocket<>{ m_pDlg=NULL; if<m_pArOut!=NULL>{m_pArOut->Close<>; deletem_pArOut; m_pArOut=NULL;} if<m_pArIn!=NULL>{ m_pArIn->Close<>; deletem_pArIn; m_pArIn=NULL;} if<m_pFile!=NULL>{m_pFile->Close<>;deletem_pFile; m_pFile=NULL;}}10、在TsDlg.h文件〔CTsDlg类的定义文件中添加下面两个文件的引用:#include"CSocket.h"#include"LSocket.h"并添加成员变量: CLSocket*m_pLSocket; //监听套接字指针 CPtrListm_connList; //连接列表和成员函数的声明: voidbackClient<CMsg*pMsg>;//向聊天室所有客户机转发消息 voidOnReceive<CCSocket*pSocket>;//获取客户机消息 voidOnAccept<>;//接受连接请求在TsDlg.cpp中,实现这三个成员函数:voidCTsDlg::OnAccept<>{ CCSocket*pSocket=newCCSocket<this>;if<m_pLSocket->Accept<*pSocket>> { pSocket->Initialize<>; m_connList.AddTail<pSocket>; CStringstrTemp; strTemp.Format<L"在线人数:%d",m_connList.GetCount<>>; m_strNum=strTemp; UpdateData<FALSE>; }elsedeletepSocket;}voidCTsDlg::OnReceive<CCSocket*pSocket>{staticCMsgmsg;do { pSocket->ReceiveMsg<&msg>; m_listMsg.AddString<msg.m_strText>; backClient<&msg>;if<msg.m_bClose> { pSocket->Close<>; POSITIONpos,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>; CStringstrTemp; strTemp.Format<L"在线人数:%d",m_connList.GetCount<>>; m_strNum=strTemp; UpdateData<FALSE>; } }deletepSocket;break; } }while<!pSocket->m_pArIn->IsBufferEmpty<>>;}voidCTsDlg::backClient<CMsg*pMsg>{ CCSocket*pSocket;for<POSITIONpos=m_connList.GetHeadPosition<>;pos!=NULL;> { pSocket=<CCSocket*>m_connList.GetNext<pos>; pSocket->SendMsg<pMsg>; }}11、完成CLSocket类的OnAccept<>函数的代码〔第6步添加的虚函数:voidCLSocket::OnAccept<intnErrorCode>{ CSocket::OnAccept<nErrorCode>;if<m_pDlg!=NULL>m_pDlg->OnAccept<>;}完成CCSocket类的OnAccept<>函数的代码〔第7步添加的虚函数:voidCCSocket::OnReceive<intnErrorCode>{ CSocket::OnReceive<nErrorCode>; m_pDlg->OnReceive<this>;}12、为对话框CTsDlg的"监听"和"停止服务"两个按钮添加消息响应函数。〔方法可以在对话框资源编辑窗口双击对应按钮,或使用类向导voidCTsDlg::OnBnClickedButtonListen<>{//TODO:Addyourcontrolnotificationhandlercodehere UpdateData<TRUE>; m_pLSocket=newCLSocket<this>;if<!m_pLSocket->Create<m_nPort>> {deletem_pLSocket; m_pLSocket=NULL; AfxMessageBox<L"创建监听套接字错误">;return; }if<!m_pLSocket->Listen<>> {deletem_pLSocket; m_pLSocket=NULL; AfxMessageBox<L"启动监听错误">;return; } GetDlgItem<IDC_EDIT_PORT>->EnableWindow<FALSE>; GetDlgItem<IDC_BUTTON_LISTEN>->EnableWindow<FALSE>; GetDlgItem<IDOK>->EnableWindow<TRUE>;}voidCTsDlg::OnBnClickedOk<>{//TODO:Addyourcontrolnotificationhandlercodehere CMsgmsg; msg.m_strText=L"服务器终止服务";deletem_pLSocket; m_pLSocket=NULL; CCSocket*pSocket;while<!m_connList.IsEmpty<>> { pSocket=<CCSocket*>m_connList.RemoveHead<>; pSocket->SendMsg<&msg>;deletepSocket; }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.h"5、从CSocket类派生一个套接字类CCSocket,用于与客户机建立连接并交换数据。如图所示:6、使用类向导,为CCSocket类添加OnReceive事件处理函数,如图所示。8、为CCSocket类添加一个指向对话框类的指针变量:
CTcDlg*m_pDlg;
为避免对话框类与套接字类交叉引用,在类的定义前添加
classCTcDlg;
修改CCSocket类的构造函数,添加一个CTcDlg*类型的参数。如图所示。
在CSocket.cpp中添加头文件的引用,并完成CCSocket类构造函数的修改:#include"TcDlg.h"CCSocket::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对象和成员函数的声明: voidOnReceive<>;//接收信息 voidReceiveMsg<>;//接收服务器发送来的消息 voidSendMsg<CString&strText,boolst>;//向服务器发送消息在TcDlg.cpp中,添加对Msg.h文件的引用和实现这三个成员函数:#include"Msg.h"voidCTcDlg::OnReceive<>{do{ ReceiveMsg<>;if<m_pSocket==NULL>return; }while<!m_pArchiveIn->IsBufferEmpty<>>;}voidCTcDlg::ReceiveMsg<>{ CMsgmsg; TRY { msg.Serialize<*m_pArchiveIn>; m_listMsg.AddString<msg.m_strText>; } CATCH<CFileException,e> { CStringstrTemp; strTemp=L"服¤t务?器¡Â重?置?连¢?接¨®!ê?连¢?接¨®关?闭À?"; m_listMsg.AddString<strTemp>; msg.m_bClose=TRUE; m_pArchiveOut->Abort<>;deletem_pArchiveIn; m_pArchiveIn=NULL;deletem_pArchiveOut; m_pArchiveOut=NULL;deletem_pFile; m_pFile=NULL;deletem_pSocket; m_pSocket=NULL; } END_CATCH}voidCTcDlg::SendMsg<CString&strText,boolst>{if<m_pArchiveOut!=NULL> { CMsgmsg; msg.m_strText=strText; msg.m_bClose=st; msg.Serialize<*m_pArchiveOut>; m_pArchiveOut->Flush<>; }}10、为对话框CTcDlg的"退出"、"连接"和"发送"三个按钮添加消息响应函数。〔方法可以在对话框资源编辑窗口双击对应按钮,或使用类向导voidCTcDlg::OnBnClickedButtonConn<>{//TODO:Addyourcontrolnotificationhandlercodehere UpdateData<TRUE>; m_pSocket=newCCSocket<this>;if<!m_pSocket->Create<>> {deletem_pSocket; m_pSocket=NULL; AfxMessageBox<L"套接字创建错误">;return; }if<!m_pSocket->Connect<m_strSName,m_nPort>> {deletem_pSocket; m_pSocket=NULL; AfxMessageBox<L"无法连接到服务器">;return; } m_pFile=newCSocketFile<m_pSocket>; m_pArchiveIn=newCArchive<m_pFile,CArchive::load>; m_pArchiveOut=newCArchive<m_pFile,CArchive::store>; UpdateData<TRUE>; CStringstrTemp; 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>;}voidCTcDlg::OnBnClickedButtonClose<>{//TODO:Addyourcontrolnotificationhandlercodehere CStringstrTemp; strTemp=m_strCName+L"离开聊天室"; SendMsg<strTemp,TRUE>;deletem_pArchiveOut; m_pArchiveOut=NULL;deletem_pArchiveIn; m_pArchiveIn=NULL;deletem_pFile; m_pFile=NULL; m_pSocket->Close<>;deletem_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、打开类向导,为TcDlg类
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 三年级数学兴趣班教学计划
- 计算机应用技术毕业生实习报告模版
- 智能化矿山开采施工质量管理措施
- 2025年新时期产业工人队伍建设中的法律保障措施范文
- 劳动教育在一二年级课堂的创新计划
- 2025年医院ICU应急预案计划
- 高中暑假社会实践活动演讲稿范文
- 社区卫生服务中心医疗纠纷处理流程
- 2025年-家庭教育指导服务计划
- 2025股权股份转让合同(范本)
- 安徽省合肥市包河区2023-2024学年九年级上学期期末化学试题
- 《酸碱罐区设计规范》编制说明
- PMC主管年终总结报告
- 售楼部保安管理培训
- 仓储培训课件模板
- 2025届高考地理一轮复习第七讲水循环与洋流自主练含解析
- GB/T 44914-2024和田玉分级
- 2024年度企业入驻跨境电商孵化基地合作协议3篇
- 《形势与政策》课程标准
- 2023年海南省公务员录用考试《行测》真题卷及答案解析
- 桥梁监测监控实施方案
评论
0/150
提交评论