网络编程技术课程设计报告_第1页
网络编程技术课程设计报告_第2页
网络编程技术课程设计报告_第3页
网络编程技术课程设计报告_第4页
网络编程技术课程设计报告_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

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

文档简介

1、题 目名称 聊天软件的开发 课 程 名 称 网络编程技术课程设计学生姓名学号系 、专 业指导教师2016年5月22日摘 要聊天程序一般采用互连网中继聊天协议,即双方即时通信的过程中必须通过第三方中转,第三方为服务器,聊天程序一般采用UDP协议,在基于UDP协议的基础上,聊天过程中消息的发送必须遵守某一种约定,这种约定规定了“进入聊室”、“发送聊天信息”和“离开聊天室”数据传输格式,中转者(服务器)通过接收客户端不同的数据格式来进行判断消息发送者欲进行的操作,然后对消息进行处理后再进行转发。本次课程设计主要是利用MFC所提供的各种控件,基于C/S模式,设计的一个简单聊天软件。关键词:Visual

2、 C+6.0,客户端-服务器(C/S)结构,简单聊天软件目 录1前言12 需求分析12.1 任务和要求12.2 应实现的功能22.3 界面及控件变量23 分析和设计4系统分析及设计思路43.2 主要控件的功能53.3 程序流程图6(一)流程运行框架6(二)服务端7(三)客户端94 具体代码实现124.1 服务器12185 课程设计总结245.1 程序运行结果或预期运行结果245.2 设计结论25参考文献27致 谢271前言本次课程设计主要是利用MFC所提供的各种控件,基于C/S模式,设计的一个简单聊天软件。聊天软件由客户端和服务器两部分构成,服务器充当“中转者”的职能,客户端将自己的消息首先发

3、给服务器,服务器再根据需要将它们转发给其他客户端。聊天程序一般采用互连网中继聊天协议,即双方即时通信的过程中必须通过第三方中转,第三方为服务器,聊天程序一般采用UDP协议,在基于UDP协议的基础上,聊天过程中消息的发送必须遵守某一种约定,这种约定规定了”进入聊天室”,”发送聊天信息”和”离开聊天室”数据传输格式,中转者(服务器)通过接收客户端不同的数据格式来进行判断消息发送者欲进行的操作,然后对消息进行处理后再进行转发,服务器根据接收到的不同消息格式做出不同的处理。2 需求分析任务和要求本次课程设计内容任务是简单群聊软件的设计与实现。三人以上为一组,其中一个同学为群聊软件的服务器端,另外同学为

4、群聊软件客户端,服务器开启后公布其IP地址和端口号,客户端用服务器的IP地址和端口号进行登录,观察服务器与客户端的显示的结果,然后由客户端发送群聊消息,观察服务器与各客户端的显示结果。具体要求如下:1.采用客户端服务器(C/S)结构,聊天室软件由客户端和服务器两部分构成,即创建两个工程,服务器(SelfRoom)和客户端(SelfChat)。2.服务器的对话框界面应具有聊天室IP、端口、开启、关闭、聊天室动态、在线用户等基本内容,而客户端的对话框界面应具有昵称、聊天室IP、端口、登录、离开、聊天记录、在线好友等基本内容,添加相应的成员函数,使程序能正常运行。3.聊天程序采用UDP协议,基于UD

5、P协议的聊天过程中遵守一种约定,这种约定规定了“进入或离开聊天室”和“发送聊天信息”数据传输格式,服务器作为“中转者”通过接收客户端不同的数据格式来进行判断消息发送者的欲进行的操作,然后对消息进行处理后再进行转发。2.2 应实现的功能此次课程设计内容是群聊软件的设计与实现,采用MFC类编程。下面介绍一下服务器和客户端所实现的功能。服务器的界面中有管理员、聊天室IP、端口、聊天室动态和在线用户列表,还有“开启”、“关闭”、“退出”按钮。运行服务器时,先进行管理员、聊天室IP、端口的配置,点击“开启”按钮后,聊天室动态的文本框里会显现“聊天室开启成功”等消息以及当时得时间,便可等待成员的加入;当有

6、成员加入时,也会有相应的提示信息,用户列表也会及时更新;当客户端发来消息,服务器会将此消息转发给每一个成员;当列表中的所有成员都离开时,服务器可点击“关闭”,即关闭聊天室。客户端的界面有您的昵称、聊天室IP、端口、聊天文本框、在线好友列表,还有“进入”、“离开”、“发送”按钮。运行客户端时,先进行昵称、聊天室IP、端口的配置,点击“进入”按钮,与服务器进行了连接;连接成功后,可发送聊天消息点击“发送”就能将消息发送到服务器,让服务器进行处理,发送的信息会显示在聊天框里,每条消息前面还附有发送消息时的时间,在线好友列表中会显示已进入聊天室的成员,可以与他们进行群聊,由于这只是简单的群聊软件,所以

7、只能发送文字信息,不具备发送表情、文件等高级功能;当有成员加入或离开聊天室时,聊天框内会有提示信息,在线好友列表也会即时更新;当客户端想离开时,可以点击“离开”按钮,即可退出聊天室。2.3 界面及控件变量(一)服务器。图2.1 服务器界面图(二)客户端。3 分析和设计系统分析及设计思路本次聊天软件采用MFC编程,需要创建2个工程,分别是客户端工程SelfChat和服务器工程SelfRoom,由于本次软件需用到套接字类,所以在创建工程的时候需要选择“Windows Sockets”复选框,并都基于基本对话框。在制作服务器的时候需要添加两个基于CSocket的套接字:CClientSocket(用

8、来监听)和CServerSocket(为每个加入聊天室的客户端生成一个相应的对象与之通信),另外添加一个C+结构体tagHeader(用于客户端和服务器之间辨识消息类型的)。在制作客户端时添加一个基于CSocket的套接字类CClientSocket(用于连接服务器通信),和服务器一样要添加一个C+结构体tagHeader。整个流程中的事件时序如下:1. 服务器配置管理员、聊天室IP以及端口后,单击“开启”按钮,此时服务器主动调用Listen()开始监听。2. 客户端配置昵称、聊天室IP以及端口后,单击“进入”按钮,此时客户端向服务器发起连接Connect()请求,若请求被接收,则紧接着发送会

9、话消息。3. 服务器的CServerSocket类接收请求并触发OnAccept()事件,该事件过程创建对应请求方客户端的CClientSocket类对象并添加到Socket队列。4. 更多成员客户端加入时,服务器重复步骤3。5. 某个成员(客户端)要发送聊天消息时,在发送信息文本框中编辑文字,单击“发送”按钮向服务器发出消息。6. 某个成员(客户端)发来的消息到达服务器,触发服务器Socket队列中对应该客户端CClientSocket类对象的OnReceive()事件,对发来的消息进行处理。7. 服务器上对应该客户端的CClientSocket类对象,根据消息头tagHeader结构中的t

10、ype字段辨别消息类型:若type=LOGIN_IO,则表示有新成员加入,用广播方式通知所有其他成员客户端,并调用服务器UpdateUser()更新服务器用户列表;若type=SEND_MESSAGE,则表示这只是普通的成员的发言信息,直接广播转发该消息就可以了。8. 服务器发出的消息到达客户端,触发客户端本地OnReceive()事件,客户端本地Socket根据消息头tagHeader结构中的type字段辨识消息类型:若type=LOGIN_IO,则表示有新成员加入或已有聊天成员下线退出,于是调用客户端UpdateUser()函数更新本地用户列表;若type=SEND_MESSAGE,则表示

11、这是聊天室中其他成员发来的消息,调用GetMsgFromRoom()函数接收之后显示在客户端的屏幕上。9. 某个成员要下线时,单击“离开”按钮,关闭本地Socket。10. 一旦某成员退出,关闭了自己客户端程序的本地Socket,就会触发其在服务器上的Socket队列中对应的CClientSocket类对象的Onclose()事件,由CClientSocket类对象发消息通知其他成员有人退出,并调用UpdateUser()更新服务器用户列表。11. 当最后一个成员离开聊天室后,管理员可单击“关闭”按钮关闭服务器。3.2 主要控件的功能服务器主要控件的功能见表3.1,客户端的主要控件功能见表3.

12、2。控件功能“管理员”文本框配置管理员名称IP控件配置聊天室IP“端口”文本框配置聊天室端口“聊天室动态”只读文本框显示聊天室的动态,包括聊天室开启、关闭的提示信息,成员登录、离开的提示信息以及聊天消息“用户在线”列表框显示已进入聊天室的成员“开启”按钮开启聊天室“关闭”按钮关闭聊天室“退出”按钮退出控件功能“您的昵称”文本框配置昵称IP控件配置聊天室IP“端口”文本框配置聊天室端口“在线好友”列表框显示已进入聊天室的成员“聊天”只读文本框显示聊天室的动态,包括聊天室开启、关闭的提示信息,成员登录、离开的提示信息以及聊天消息“发送”信息文本框编辑要发送的消息“发送”按钮将消息发送出去“进入”按

13、钮进入聊天室“离开”按钮离开聊天室“退出”按钮退出3.3 程序流程图(一)流程运行框架图3.1 流程运行框架程序流程图(二)服务端“开启”图3.2 服务器“开启”按钮程序流程图图3.3 服务器OnReceive()事件程序流程图图3.4 服务器UpdateUser函数程序流程图4.服务器OnClose()事件流程图 如图3.5图3.5 服务器OnClose()事件流程图(三)客户端“进入”按钮事件流程图 如图3.6图3.6 客户端“进入”按钮事件程序流程图“发送”按钮事件流程图 如图3.7图3.7 客户端“发送”按钮流程流程图 OnReceive()事件流程图 如图3.8图3.8 客户端本地O

14、nReceive()事件流程图4.客户端的GetMsgFromRoom()和UpdateUser()函数流程图 如图3.9图3.9 客户端的GetMsgFromRoom()和UpdateUser()函数程序流程图“离开”函数流程图 如图3.10.图3.10 客户端的“离开”函数流程图4具体代码实现4.1 服务器1.单击“开启”按钮,添加函数:void CSelfRoomDlg:OnButton1() / TODO: Add your control notification handler code here UpdateData(); /刷新界面,获得用户输入 m_pSocket=new C

15、ServerSocket; BYTE nFild4; CString sIP; ServerIP.GetAddress(nFild0,nFild1,nFild2,nFild3); /获取管理员配置的IP sIP.Format(%d.%d.%d.%d,nFild0,nFild1,nFild2,nFild3); CTime time=CTime:GetCurrentTime(); /获取当前时间 /下面开始输入完整性验证 if(m_strName.IsEmpty() AfxMessageBox(请先登记管理员名!); return; if(sIP.IsEmpty() AfxMessageBox(请

16、配置聊天室IP!); return; if(sPort.IsEmpty() AfxMessageBox(请配置要开放的窗口!); return; /界面 m_Admin.EnableWindow(false); ServerIP.EnableWindow(false); ServerPort.EnableWindow(false); m_Start.EnableWindow(false); m_Stop.EnableWindow(true); m_Exit.EnableWindow(false); /开启聊天室,首先创建用于监听的套接字 if(m_pSocket-Create(atoi(sPo

17、rt),1,sIP) m_MessageList.SetWindowTextA(); m_MessageList.ReplaceSel(聊天室开启成功!rn); CString t=time.Format(%Y-%m-%d); m_MessageList.ReplaceSel(日期:+t+rn); t=time.Format(%H:%M:%S); /获得聊天室开启的时刻信息 theApp.m_strName=m_strName; /记录管理员名 m_MessageList.ReplaceSel(t+管理员+theApp.m_strName+开放聊天室rn); if(m_pSocket-List

18、en() /监听开始 m_MessageList.ReplaceSel(等待成员加入rn); /现在暂时还无人加入聊天,因此在线用户列表中仅管理员一人 m_UserList.ResetContent(); m_UserList.AddString(theApp.m_strName+(管理员); this-SetWindowTextA(管理员:+m_strName+-SelfRoom);2.客户端用户发送消息到达服务器的OnReceive()事件:void CClientSocket:OnReceive(int nErrorCode) / TODO: Add your specialized c

19、ode here and/or call the base classchar buff1sizeof(Header); memset(buff1,0,sizeof(buff1); Receive(buff1,sizeof(buff1);/首先接收信息的头部 this-AsyncSelect(FD_CLOSE|FD_READ|FD_WRITE); Header*header=(Header*)buff1; int length=header-len; char type=header-type;/解析头部内容 if(type=LOGIN_IO) /头部类型为LOGIN_IO,表示是新成员加入

20、char buff1000; memset(buff,0,sizeof(buff); Receive(buff,length);/继续接收这条信息的数据部分(新成员名) this-AsyncSelect(FD_CLOSE|FD_READ|FD_WRITE); m_dlgServer-UpdateData(); CTime time=CTime:GetCurrentTime(); CString t=time.Format(%H:%M:%S); CEdit*p_Edit=(CEdit *):AfxGetMainWnd()-GetDlgItem(IDC_EDIT_INFO); /生成通知信息 CS

21、tring strTemp=t+ +CString(buff)+进入聊天室/rn; p_Edit-ReplaceSel(strTemp); m_strName=buff;/将新成员的用户名登记在服务器对应的Socket中 Header head; head.type=SEND_MESSAGE; head.len=strTemp.GetLength(); Header head_history; head_history.type=SEND_MESSAGE; /生成欢迎信息 m_dlgServer-m_history+=m_strName+欢迎您加入!; head_history.len=m_d

22、lgServer-m_history.GetLength();CClientSocket *curr=NULL;POSITION pos=clist-GetHeadPosition();while(pos!=NULL)curr=(CClientSocket *)clist-GetNext(pos);if(curr-m_strName=m_strName)/为新加入的那个成员发送欢迎信息curr-Send(char*)&head_history,sizeof(Header);curr-Send(m_dlgServer-m_history,m_dlgServer-m_history.GetLeng

23、th();else/向聊天室中其他的老成员发送通知信息,告知有新成员加入curr-Send(char*)&head,sizeof(Header);curr-Send(strTemp,strTemp.GetLength();m_dlgServer-UpdateUser(this);/更新用户列表if(type=SEND_MESSAGE)/头部类型为SEND_MESSAGE,表示是成员之间的聊天信息char buff1000;memset(buff,0,sizeof(buff);Receive(buff,sizeof(buff);this-AsyncSelect(FD_CLOSE|FD_READ|

24、FD_WRITE) ;CTime time=CTime:GetCurrentTime();CString t=time.Format(%H:%M:%S);CString nikeName=this-m_strName;CString strTemp=t+ +nikeName+说:+CString(buff)+rn;CString str=nikeName+ +t+rn+ +CString(buff);CEdit*p_Edit=(CEdit*):AfxGetMainWnd()-GetDlgItem(IDC_EDIT_INFO);p_Edit-ReplaceSel(strTemp);CClient

25、Socket*curr=NULL;POSITION pos=clist-GetHeadPosition(); while(pos!=NULL)/向聊天室内所有成员转发聊天信息内容 curr=(CClientSocket*)clist-GetNext(pos); curr-Send(char*)header,sizeof(Header); curr-Send(str,str.GetLength(); CSocket:OnReceive(nErrorCode);CSocket:OnReceive(nErrorCode);3.服务器检测到新成员加入,调用UpdateUser()函数更新用户列表:vo

26、id CSelfRoomDlg:UpdateUser(CClientSocket *pSocket) m_UserList.ResetContent(); m_UserList.AddString(theApp.m_strName+管理员); CString user_info; user_info=theApp.m_strName+(管理员)+&; if(pSocket!=NULL) CClientSocket *pSock=NULL; POSITION pos=pSocket-clist-GetHeadPosition(); while(pos!=NULL) pSock=(CClientS

27、ocket *)pSocket-clist-GetNext(pos); m_UserList.AddString(pSock-m_strName); user_info+=(pSock-m_strName+&); Header head; head.type=LOGIN_IO; head.len=user_info.GetLength(); POSITION po=pSocket-clist-GetHeadPosition(); while(po!=NULL) pSock=(CClientSocket *)pSocket-clist-GetNext(po); pSock-Send(char *

28、)&head,sizeof(Header); pSock-Send(LPCTSTR)user_info,user_info.GetLength(); 4.成员退出,关闭自己的Socket,触发服务器的OnClose()事件:void CClientSocket:OnClose(int nErrorCode) / TODO: Add your specialized code here and/or call the base classPOSITION pos=clist-Find(this); if(pos!=NULL) clist-RemoveAt(pos); /移除服务器Socket队列

29、中的套接字 CTime time=CTime:GetCurrentTime(); CString t=time.Format(%H:%M:%S);CEdit*p_Edit=(CEdit*)m_dlgServer-GetDlgItem(IDC_EDIT_INFO); CString strTemp=t+ +this-m_strName+离开聊天室rn; p_Edit-ReplaceSel(strTemp); Header head; head.type=SEND_MESSAGE; head.len=strTemp.GetLength(); CClientSocket*curr=NULL; POS

30、ITION pos=clist-GetHeadPosition(); while(pos!=NULL) /将此用户离开的消息告知其他成员 curr=(CClientSocket*)clist-GetNext(pos); curr-Send(char*)&head,sizeof(Header); curr-Send(strTemp,strTemp.GetLength(); m_dlgServer-UpdateUser(this); /更新服务器列表 this-Close(); delete this; CSocket:OnClose(nErrorCode);4.2客户端1.客户端“进入”按钮的事

31、件过程代码如下:void CSelfChatDlg:OnButton1() / TODO: Add your control notification handler code here UpdateData(); m_pSocket=new CClientSocket; m_pSocket-GetDlg(this); /获取主界面指针 BYTE nFild4; CString sip; ServerIP.GetAddress(nFild0,nFild1,nFild2,nFild3); sip.Format(%d.%d.%d.%d,nFild0,nFild1,nFild2,nFild3); /

32、获取用户输入的服务器IP /输入完整性验证 if (m_strName.IsEmpty() AfxMessageBox(给自己起个昵称吧!); return; if(sip.IsEmpty() AfxMessageBox(请指定IP地址!); return; if(strport.IsEmpty() AfxMessageBox(请指定连接端口!); return; /发起连接 if(!m_pSocket-Create() AfxMessageBox(网络创建错误!); m_pSocket-Close(); return; if(!m_pSocket-Connect(sip,atoi(strpo

33、rt) AfxMessageBox(连接服务器失败!); m_pSocket-Close(); return; /界面 m_Usr.EnableWindow(false); ServerIP.EnableWindow(false); m_port.EnableWindow(false); m_Enter.EnableWindow(false); m_Quit.EnableWindow(true); m_EditWords.EnableWindow(true); m_EditWords.SetFocus(); m_Send.EnableWindow(true); m_Exit.EnableWin

34、dow(false);Header head; head.type=LOGIN_IO; head.len=m_strName.GetLength(); m_pSocket-Send(char*)&head,sizeof(Header); m_pSocket-Send(m_strName,m_strName.GetLength(); /发送会话消息 theApp.m_strName=m_strName; m_MessageList.SetWindowTextA(); this-SetWindowTextA(m_strName+-SelfChat);/标题栏实时动态显示用户名2.“发送”按钮的事件

35、处理代码如下:void CSelfChatDlg:OnButton3() / TODO: Add your control notification handler code hereUpdateData();if(m_strMessage=)AfxMessageBox(不能发送空消息);m_EditWords.SetFocus();return; Header head; head.type=SEND_MESSAGE;/聊天内容,消息头类型为SEND_MESSAGE head.len=m_strMessage.GetLength();m_pSocket-Send(char*)&head,si

36、zeof(Header); if(m_pSocket-Send(m_strMessage,m_strMessage.GetLength()m_strMessage=;UpdateData(FALSE);m_EditWords.SetFocus();return;elseAfxMessageBox(网络传输错误!);3.客户端本地OnReceive()事件过程:void CClientSocket:OnReceive(int nErrorCode) / TODO: Add your specialized code here and/or call the base classchar buff

37、sizeof(Header); memset(buff,0,sizeof(buff); Receive(buff,sizeof(buff); this-AsyncSelect(FD_CLOSE|FD_READ|FD_WRITE); Header *header=(Header*)buff; int length=header-len; char type=header-type; if(type=SEND_MESSAGE) chatDlg-GetMsgFromRoom(); if(type=LOGIN_IO) chatDlg-UpdateUser(); CSocket:OnReceive(nE

38、rrorCode);CSocket:OnReceive(nErrorCode);4.对于接受两类不同消息分别调用两个处理GetMsgFromRoom()和UpdateUser()函数,代码如下:BOOL CSelfChatDlg:GetMsgFromRoom() char buff1000; memset(buff,0,sizeof(buff); m_pSocket-Receive(buff,sizeof(buff);/接受信息 m_pSocket-AsyncSelect(FD_CLOSE|FD_READ|FD_WRITE); CString strTemp=buff; strTemp+=rn

39、; m_MessageList.ReplaceSel(strTemp);/直接显示在界面上即可 return TRUE;void CSelfChatDlg:UpdateUser() char buff1000; memset(buff,0,sizeof(buff); m_pSocket-Receive(buff,sizeof(buff);/接收到最新的在线用户名单 m_pSocket-AsyncSelect(FD_CLOSE|FD_READ|FD_WRITE); CString user_info=buff; CString array100; int b=0; for(int i=0;ius

40、er_info.GetLength();i+) if(i!=(user_info.GetLength()-1) if(user_infoi=&) b+; else arrayb=arrayb+user_infoi; m_UserList.ResetContent(); for(int j=0;jClose(); delete m_pSocket;/离开时记得关闭,销毁Scoket m_UserList.ResetContent(); m_MessageList.ReplaceSel(你已经退出聊天室!); this-SetWindowTextA(聊天室客户端-SelfChat);/界面 m_Usr.EnableWindow(true); m_Usr.SetFocus(); ServerIP.EnableWindow(true); m_port.EnableWindow(true); m_Enter.EnableWindow(true); m_Quit.EnableWindow(false); m_EditWords.EnableWindow(false); m_Send.EnableWindow(false); m_Exit.EnableWindow(true);5 课程设计总结5.1 程序运行结果或预

温馨提示

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

评论

0/150

提交评论