1、支持多个客户端的连接,在服务器和多个客户端之间进行数据传输;接收客户端发送的消息,并显示在一个列表框中;在用户连接上后有提示,显示出连接的用户名字;发送信息时可以显示聊天的所有记录;2.3系统主要功能和主要功能描述:服务器端聊天程序必须能够做3件事情:(1)服务器聊天程序要在待定的端口上等待来自聊天客户的连接请求,并且需要维护一个客户连接表,以记录所有成功的连接。(2)服务器聊天程序要及时接受从各个聊天客户发送过来的信息,然后把这些信息转发到一个或多个客户连接。对于公共聊天室,服务器将把接受到的信息向除源端外的所有客户发送过去。(3)服务器还要监控这些连接的状态,在客户主动离开或发生故障时从列
2、表中删除相应的表项,并及时更新连接表。这些要求可以通过CSocket类提供的功能实现。从CSocket派生出两个类CListenSocket和CClientSocket,它们分别用来侦听客户的连接请求和建立与客户的连接。服务器只需要一个侦听套接字CListenSocket,然后根据客户的连接请求动态创建客户套接字CClientSocket。客户套接字的数量是不可预知的,因此需要一个列表来记录。MFC的CPtrList类就能实现这种功能。客户端聊天程序需要完成以下几个功能:(1)客户端聊天程序要负责建立和维护与服务器的连接,通过获取用户的设置尝试与服务器的连接,并且随时检测连接的状态。(2)客户
3、端聊天程序要把用户输入的信息及时发送到聊天服务器。一般情况下,当用户输入一行信息并且按下回车键后聊天程序就要把这一行信息发送出去,才能及时地满足用户的交互需求。(3)要随时准备好接受来自服务器的信息,随时把接受到的信息显示出来,让用户及时看到对方的响应。(4)在用户退出聊天过程是要关闭与服务器的连接。比较好的做法是提前通知服务器或者直接给服务器发送一条退出通知,使得服务器能够及时掌握客户端的连接状态,把对方客户的退出信息及时发送到对等实体上。客户端聊天程序需要使用一个通过CSocket类派生出来的CChatSocket类来实现。该套接字用来发送一个与服务器的连接请求和维持与服务器的连接,发送和
4、接收聊天信息,完成上述各项功能。3.详细设计3.1设计流程图3.2客户端的实现(1)首先启动Visual C+ 6.0,利用MFC AppWizardEXE建立一个新的MFC工程,工程名为tcpclient,在MFC AppWizard Step1的时候选择Dialog based 即基于对话框,在Step4时勾选Windows Sockets选项(如图3.11),其他默认值下一步。图3.11 MFC的设置 (2)客户端主要分为三个窗口,第一个是连接窗口,需要输入连接到服务器的相关设置信息;第二个是聊天信息显示窗口,该窗口显示登录服务器以来发送和接收到的消息;第三个是消息编辑发送窗口,需要输入
5、你要发送的信息内容并发送。 新建一个对话框,并添加各种控件(见控件表3.1)如下图:图3.12 聊天窗口布局表3.1 控件类型及各自ID标题控件类型控件ID连接StaticIDC_STATIC信息区我的ID:服务器ID:端口号(默认520)连接服务器ButtonIDC_connet发送(回车)IDC_send编辑框1EditIDC_EDIT1编辑框2IDC_EDIT2编辑框3IDC_EDIT3编辑框4IDC_EDIT4编辑框5IDC_EDIT5其中编辑框1:服务器IP;编辑框2:端口号;编辑框3:消息显示区;编辑框4:消息编辑区;编辑框5:我的ID。(3)服务器IP编辑框控件IDC_EDIT1
6、对应的成员变量为OnChangeEdit1 端口号编辑框控件IDC_EDIT2对应的成员变量为OnChangeEdit2 消息显示区编辑框控件IDC_EDIT3对应的成员变量为OnChangeEdit3 消息编辑区编辑框控件IDC_EDIT4对应的成员变量为OnChangeEdit4 我的ID编辑框控件IDC_EDIT5对应的成员变量为OnChangeEdit5(4)下面重点介绍一下单击连接服务器按钮时的处理网络连接的函数。代码设置如下:void CTcpclientDlg:Onconnet() / TODO: Add your control notification handler cod
7、e here if(clconect) clconect.Close(); CString ipstr,portstr; int port; GetDlgItemText(IDC_EDIT1,ipstr); GetDlgItemText(IDC_EDIT2,portstr); GetDlgItemText(IDC_EDIT5,clientname); portstr.TrimLeft(); portstr.TrimRight(); port=atoi(portstr); if(port0&portEnableWindow(false); cw=GetDlgItem(IDC_EDIT2); cw
8、=GetDlgItem(IDC_connet); cw=GetDlgItem(IDC_EDIT5); SetDlgItemText(IDC_EDIT3,已设名字+clientname+rn连接服务器成功); CString enterinfo=clientname+进入聊天室; int len=enterinfo.GetLength(); clconect.Send(enterinfo,len); else clconect.Close(); MessageBox(连接失败,请检查IP与端口是否与服务器一致!或者服务器没打开,连接错误,MB_ICONERROR); else MessageBo
9、x(端口或IP输入有误,请重新输入设计步骤:创建字符串ipstr(保存IP),portstr(保存端口),clientname(用户名),整型port(端口号)。利用GetDlgItemText将各个编辑框中的信息赋给相应的变量。监视端口号和IP格式并设置相应错误提示(如下图)。 图3.13 连接错误提示图3.14 端口或IP错误提示创建套接字clconect,设置成功创建后相关控件为只读(避免误操作)。设置建立连接后相应提示。(5)接下来就是对话框中的发送(回车)按钮的函数,代码设置如下:Onsend() CString str; GetDlgItemText(IDC_EDIT4,str);
10、 str=clientname+str; int len=str.GetLength(); if(clconect.Send(str,len)1)SetDlgItemText(IDC_EDIT4, 定义字符串str用于保存输入的消息,调整格式后使用CSocket的操作函数send将消息发送到服务器。(6)要显示客户端接收到来自服务器其他用户的信息,代码设置如下:onrev() CString str,str1; char ss256; for(int j=0;jLineScroll(ce-GetLineCount()-1);创建字符串str、str1,字符数组ss。接受来自服务器套接字的信息数
11、据保存到ss中,调整格式后将其打印到消息区。(7)当与服务器断开连接时弹出警告,如下图: 图3.15 失去连接提示oncl() MessageBox(失去连接或者找不到服务器 CWnd *cw=GetDlgItem(IDC_EDIT1); cw-EnableWindow(true); cw=GetDlgItem(IDC_EDIT2); cw=GetDlgItem(IDC_connet); cw=GetDlgItem(IDC_EDIT5);当失去与服务器的连接后,重新将连接服务器设置编辑框启用等待下次连接。(8)在退出程序时的提示,如下图:图3.16 退出确认OnClose() int conf
12、irm=MessageBox(确定退出吗请确定,MB_YESNO|MB_ICONQUESTION); if(confirm=IDYES) CString enterinfo=clientname+退出了聊天室 int len=enterinfo.GetLength(); clconect.Send(enterinfo,len); CDialog:OnClose();当退出程序时,弹出确认对话框。当选择“是”时,将用户退出信息发送至服务器并关闭对话框。至此客户端的核心部分介绍完毕。3.3服务端的实现(1)和客户端一样,仍然建立一个基于对话框的工程,工程名为tcpserver,同样,注意一定不要忘
13、记在Step4时勾选Windows Sockets选项。其他默认下一步。(2)客户端主要分为三个窗口,第一个是服务器信息设置窗口,需要输入服务器的相关设置信息;第二个是聊天信息显示窗口,该窗口显示启动服务器以来发送和接收到的消息;新建一个对话框,并添加各种控件(见控件表3.2)如下图: 图 3.21表3.2 控件类型及各自ID服务器设置消息区服务器名称:端口:启动服务器IDC_listen服务器名称;端口号。(3)消息显示区编辑框控件IDC_EDIT1对应的成员变量为OnChangeEdit1 消息编辑区编辑框控件IDC_EDIT2对应的成员变量为OnChangeEdit2 服务器名称编辑框控
14、件IDC_EDIT3对应的成员变量为OnChangeEdit3 端口号编辑框控件IDC_EDIT4对应的成员变量为OnChangeEdit4 (4)下面重点介绍一下单击启动服务器按钮时的处理网络连接的函数。void CTcpseverDlg:Onlisten() / Beep(2000,100); GetDlgItemText(IDC_EDIT3,ipstr); severname=ipstr; GetDlgItemText(IDC_EDIT4,portstr); if(cslisten.Create(port) / cslisten.Bind(port); cslisten.Listen()
15、; cslisten.setp(this,csnum); CWnd *cw=GetDlgItem(IDC_EDIT3); cw=GetDlgItem(IDC_EDIT4); cw=GetDlgItem(IDC_listen); cw=GetDlgItem(IDC_EDIT1);SetWindowText(服务器名:+severname+rn等待用户连接,监听端口:+portstr+.设置监听端口失败,端口可能被其它程序占用 cslisten.Close();端口输入有误,请重新输入 创建字符串ipstr(保存IP),portstr(保存端口),整型port(端口号)。 图 3.22 图 3.2
16、3设置建立连接后相应提示。 CString str,history; GetDlgItemText(IDC_EDIT1,history); GetDlgItemText(IDC_EDIT2,str); str=severname+ int sended; for(int i=1;i定义字符串str用于保存输入的消息,调整格式后使用CSocket的操作函数send将消息发送到各个客户端。(6)要显示服务器接收到来自客户端其他用户的信息,代码设置如下:onrev(int mynum)int i; char ss100;100; csrevmynum.Receive(ss,100); str.For
17、mat( for(i=1;i+)if(csrevi) if(csrevi) csrevi.Send(str,100); GetDlgItemText(IDC_EDIT1,str1); str=str1+ SetDlgItemText(IDC_EDIT1,str); CEdit *ce=(CEdit*)GetDlgItem(IDC_EDIT1); ce-(7)当有新用户进入时,显示“XXX进入”。代码如下:onac() CString str1,str; GetDlgItemText(IDC_EDIT1,str1); CString str2=rn进入 str=str1+str2; SetDlg
18、ItemText(IDC_EDIT1,str); cslisten.Accept(csrev+csnum); csrevcsnum.setp(this,csnum);图3.24 退出确认 CString str=服务器即将退出 int confirm=MessageBox(确定退出服务器?所有用户都将断开 int len=str.GetLength(); for(int i=1;i+) if(csrevi) csrevi.Send(str,len); str=severname+退出,与服务器连接已断开 len=str.GetLength(); for( i=1;当选择“是”时,将服务器关闭信息发送至各个客户端并关闭对话框。至此服务器端的核心部分介绍完毕。4.心得体会:通过一周的课程设计,让我学会了很多东西,也算能比较熟练地掌握MFC这一个软件了,动手能力增强了不少。参考文献:【1】 姚领田 精通MFC程序设计 北京人民邮电出版社 2007【2】 杨富国 Visual C+程序开发案例解析 北京清华大学出版社 2006.3
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1