MFCWinsock类cs聊天程序开发_第1页
MFCWinsock类cs聊天程序开发_第2页
MFCWinsock类cs聊天程序开发_第3页
MFCWinsock类cs聊天程序开发_第4页
MFCWinsock类cs聊天程序开发_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

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

文档简介

1、案例开发与分析聊天程序的开发一、客户端任务1:创建客户端框架程序,设计用户界面,并实现与服务器的连接。1. 创建一个空白工作区,并命名为Chat。2. 在Chat工作区,用MFC AppWizard创建基于对话框的项目ChatClient,并在Step2中选中Windows Socket选项。3. 在对话框中添加控件,如下图所示:4. 对话框中的控件属性如下表:表1 控件属性控件类型控件IDCaption其他List BoxIDC_LIST_MESSAGE不选SortList BoxIDC_LIST_ONLINE_USERS不选SortEdit BoxIDC_EDIT_MESSAGE选中Mul

2、tiline和VerticalScrollRadio ButtonIDC_RADIO_GROUP群聊Radio ButtonIDC_RADIO_PRIVATE私聊ButtonIDC_BUTTON_LOGIN登录ButtonIDC_BUTTON_LOGOUT退出5. 用ClassWizard为控件对象定义相应的成员变量,如下表所示:表2 控件对应成员变量控件ID控件类型成员变量名IDC_EDIT_MESSAGECStringm_strMessageIDC_LIST_MESSAGECListBoxm_listMessageIDC_LIST_ONLINE_USERSCListBoxm_listUse

3、rs6. 添加对话框,ID为IDD_DIALOG_LOGIN,Caption为“登录”。7. 在对话框中添加控件,如下图所示:8. 对话框中的控件属性如下:表3 登录对话框控件属性控件类型控件IDCaption其他Edit BoxIDC_EDIT_IPEdit BoxIDC_EDIT_PORTEdit BoxIDC_EDIT_USERNAMEEdit BoxIDC_EDIT_PASSWORD选Styles->PasswordButtonIDOK连接选Styles->Default ButtonButtonIDCANCEL取消9. 添加一个新类,类名为CLogin,基类为CDialo

4、g,Dialog ID为IDD_DIALOG_LOGIN。10. 用ClassWizard为对话框的控件对象定义成员变量,如下表所示:表4 登录对话框控件对应成员变量控件ID控件类型成员变量名IDC_EDIT_IPCStringm_strIPIDC_EDIT_PASSWORDCStringm_strPasswordIDC_EDIT_PORTUINTm_nPortIDC_EDIT_USERNAMECStringm_strUserName11. 为CChatClientDlg类添加“登录”按钮的单击事件消息处理函数OnButtonLogin(),并添加如下代码:CLoginDlg dlg;int

5、nRet = -1;nRet = dlg.DoModal();编译项目并运行,单击登录按钮,看看运行情况。12. 添加一个从CSocket类派生的新类CMySocket,添加类型为CChatClientDlg*的成员变量m_pDlg,并修改默认构造函数和析构函数如下:CMySocket:CMySocket(CChatClientDlg *pDlg)m_pDlg = pDlg;CMySocket:CMySocket()m_pDlg = NULL;13. 为CChatClientDlg类添加类型为CMySocket*的成员变量m_pMySocket,类型为BOOL的成员变量m_bGroupChat

6、。14. 在CChatClientDlg:OnInitDialog()中添加如下代码:/ TODO: Add extra initialization herem_bGroupChat = TRUE; / 默认聊天方式为群聊(CButton*)GetDlgItem(IDC_RADIO_GROUP)->SetCheck(TRUE);(CButton*)GetDlgItem(IDC_BUTTON_LOGOUT)->EnableWindow(FALSE);(CEdit*)GetDlgItem(IDC_EDIT_MESSAGE)->EnableWindow(FALSE);15. 在C

7、ChatClientDlg类的OnButtonLogin()中添加如下代码:void CChatClientDlg:OnButtonLogin() / TODO: Add your control notification handler code hereCLoginDlg dlg;int nRet = -1;nRet = dlg.DoModal(); / 新增加的代码switch(nRet)case IDOK:m_pMySocket = new CMySocket(this);if(!m_pMySocket->Create()delete m_pMySocket;m_pMySocke

8、t = NULL;AfxMessageBox("创建套接字失败!");return;if(!m_pMySocket->Connect(dlg.m_strIP, dlg.m_nPort)delete m_pMySocket;m_pMySocket = NULL;AfxMessageBox("连接服务器失败!");return;(CButton*)GetDlgItem(IDC_BUTTON_LOGOUT)->EnableWindow(TRUE);(CButton*)GetDlgItem(IDC_BUTTON_LOGIN)->EnableWi

9、ndow(FALSE);(CEdit*)GetDlgItem(IDC_EDIT_MESSAGE)->EnableWindow(TRUE);break;case IDCANCEL:break;default:break;编译项目并运行,单击登录按钮,看看运行情况。二、服务器端任务1:创建服务器框架程序,创建监听套接字并接受连接请求。1. 在Chat工作区,用MFC AppWizard创建基于对话框的项目ChatServer,并在Step2中选中Windows Socket选项。2. 添加一个从CSocket类派生的CListenSocket类,为该类添加类型为CChatServerDlg*

10、的成员变量m_pDlg,并修改构造函数和析构函数如下:CListenSocket:CListenSocket(CChatServerDlg* pDlg)m_pDlg = pDlg;CListenSocket:CListenSocket()m_pDlg = NULL;3. 为CChatServerDlg类添加类型为CListenSocket*的成员变量m_pListenSocket4. 在CChatServerDlg类的OnInitDialog()中添加如下代码:/ TODO: Add extra initialization herem_pListenSocket = new CListenS

11、ocket(this);if(!m_pListenSocket->Create(8000)delete m_pListenSocket;m_pListenSocket = NULL;AfxMessageBox("创建套接字错误!");return FALSE;if(!m_pListenSocket->Listen()delete m_pListenSocket;m_pListenSocket = NULL;AfxMessageBox("启动监听错误!");return FALSE;5. 为CListenSocket类添加虚函数OnAccept

12、(),并添加如下代码:CSocket:OnAccept(nErrorCode);m_pDlg->OnAccept();6. 给项目添加CClientSocket类,该类从CSocket类派生,用于服务器与客户机进行消息传输。给该类添加类型为CChatServerDlg*的成员变量m_pDlg,并修改构造函数和析构函数如下:(注意,也应修改类声明中的构造函数原型)CClientSocket:CClientSocket(CChatServerDlg* pDlg)m_pDlg = pDlg;CClientSocket:CClientSocket()m_pDlg = NULL;7. 为CChat

13、ServerDlg类添加成员函数void OnAccept(void),并添加如下代码:CClientSocket* pSocket = new CClientSocket(this);m_pListenSocket->Accept(*pSocket);编译项目,并运行服务器和客户机,试一试客户机是否能够连接服务器。任务3:定义消息格式、消息类型,实现用户的登录。图1 客户机/服务器之间的消息传输顺序图表1 消息格式序号字段名类型长度说明1type整型4字节消息的类型2username字符串20字节用户名3data字符串256字节数据,如文字消息表2 消息类型序号种类说明1LOGIN_R

14、EQUEST登录请求消息2LOGIN_SUCCESS登录成功消息3LOGIN_FAILED登录失败消息4LOGOUT_REQUEST注销消息5ADD_USER增加用户消息6REMOVE_USER删除用户消息7PRIVATE_MESSAGE私聊消息8PUBLIC_MESSAGE群聊消息连接并登录服务器的顺序图大致如下:实现过程:一、客户端1 在客户端的对话框类的头文件中添加如下代码:enum PROTO_TYPE / 消息类型定义LOGIN_REQUEST,LOGIN_SUCCESS,LOGIN_FAILED,LOGOUT_REQUEST,ADD_USER,REMOVE_USER,PRIVATE

15、_CHAT,PUBLIC_CHAT;typedef struct tagPacket / 数据包格式定义PROTO_TYPE type;char username20;char data256; Packet;2 在CChatClientDlg:OnButtonLogin()中的case IDOK:下添加如下代码:(创建套接字,并连接服务器。连接成功后创建登录数据包并发送至服务器)case IDOK:m_pMySocket = new CMySocket(this);if(!m_pMySocket->Create()delete m_pMySocket;m_pMySocket = NUL

16、L;AfxMessageBox("创建套接字失败!");return;if(!m_pMySocket->Connect(dlg.m_strIP, dlg.m_nPort)delete m_pMySocket;m_pMySocket = NULL;AfxMessageBox("连接服务器失败!");return;/ 连接成功后发送登录数据包至服务器Packet packet;memset(&packet, 0, sizeof(Packet);packet.type = LOGIN_REQUEST;strcpy(packet.username,

17、 dlg.m_strUserName);strcpy(packet.data, dlg.m_strPassword);m_pMySocket->Send(&packet, sizeof(Packet);break;3 在CMySocket类中重载OnReceive()函数,并添加如下代码:(当套接字收到数据包时,MFC框架会调用该函数,而该函数在内部调用对话框的OnReceive()函数对接收的数据包进行相应的处理)CSocket:OnReceive(nErrorCode);m_pDlg->OnReceive();4 在CChatClientDlg类中添加void OnRe

18、ceive(void)函数,接收服务器发送的数据包,并根据数据包类型(在这里是登录成功数据包)进行相应处理。Packet packet;memset(&packet, 0, sizeof(Packet);m_pMySocket->Receive(&packet, sizeof(Packet);switch(packet.type)case LOGIN_SUCCESS:m_listMessage.AddString("login succeed.");(CButton*)GetDlgItem(IDC_BUTTON_LOGOUT)->EnableWi

19、ndow(TRUE);(CButton*)GetDlgItem(IDC_BUTTON_LOGIN)->EnableWindow(FALSE);(CEdit*)GetDlgItem(IDC_EDIT_MESSAGE)->EnableWindow(TRUE);break;5 在服务器端的CChatServerDlg.h文件的开头添加如下的结构体,用于保存在线用户的名称和对应的套接字指针,以实现一对一的聊天消息的转发:typedef struct tagUserInfochar *username;CClientSocket* pSocket; UserInfo;二、服务器端1 在服务器

20、端的对话框类的头文件中添加如下代码:enum PROTO_TYPE / 消息类型定义LOGIN_REQUEST,LOGIN_SUCCESS,LOGIN_FAILED,LOGOUT_REQUEST,ADD_USER,REMOVE_USER,PRIVATE_CHAT,PUBLIC_CHAT;typedef struct tagPacket / 数据包格式定义PROTO_TYPE type;char username20;char data256; Packet;2 在服务器端的CChatServerDlg类中添加类型为CPtrList类型的成员变量m_listUser,当用户登录服务器之后,在该链

21、表中添加用户的信息(指向UserInfo结构体类型的指针)。3 在重载CListenSocket类的OnAccept()函数,并添加如下代码:CSocket:OnAccept(nErrorCode);m_pDlg->OnAccept();4 在CChatServerDlg类中添加void OnAccept(void)函数,在该函数中服务器接收客户端的连接请求,生成该用户的UserInfo结构信息,并把该信息添加到m_listUser链表中,具体代码如下:CClientSocket* pSocket = new CClientSocket(this);m_pListenSocket->Accept(*pSocket);UserInfo *pUserInfo = new Use

温馨提示

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

评论

0/150

提交评论