版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、河海大学计算机及信息工程学院mfc课程设计报告题 目 聊天室程序设计 学 号 专 业 授课班号 学生姓名 指导教师 完成时间 题目:设计一个聊天室系统,实现多人一起聊天。一. 引言1.1开发背景随着网络信息时代的来临,internet应用越来越广泛,人们越来越习惯于在网上获取和交流信息。据调查显示,80%以上的人上网都会打开聊天工具来聊天,而几乎每一个年轻人都会去聊天。使用网上聊天已经成为现代年轻人一种新的交往方式。聊天室更适合于陌生人之间进行较为主观、感兴化的讨论。所以有大部分的人会进入聊天室聊天,它会给人一个完全自由的聊天世界。因此我联系所学的mfc知识,决定做一个简易的聊天室程序。1.2
2、开发环境以及运行环境1.2.1开发环境l intel pentium 4 2.0ghz,512m内存,80g硬盘l microsoft windows xp professionall microsoft visual c+ 6.01.2.2运行环境l intel pentium 2及以上处理器,32m以上内存,4g以上硬盘l microsoft windows xp操作系统l 800*600或以上的屏幕分辨率二需求分析1、 用winsock实现简单的网络聊天;2、 在mfc开发平台上编写一个聊天系统; 3、 得server和client之间可以相互通信; 4、 多人能够发送信息至服务器,首先
3、显示进入聊天室的成员名,然后显示对方名字和聊天信息,可以并发执行。三、算法分析 建立连接过程流程图如下:四、详细设计程序个模块代码如下: 1.客户端 (1)通过appwizard生成基于对话框的应用程序chatclient,在向导的第二步选择windowssockets的支持,其余步骤均用默认值。 (2)增加一个登录服务器的对话框资源,其id为idd_setup,然后通过classwizard生成对应的基于cdialog的类csetupdlg。 (3)给对话框csetupdlg增加3个编辑框,用来输入登录信息(聊天代号、服务器地址以及服务器端口号), (4)通过classwizard生成对应的
4、基于csocket的类cchatsocket。 (5)给cchatsocket类声明一个主对话框cchatclientdlg指针类型的私有成员变量,其代码如下: protected: cchatclientdlg* m_pdlg;并且在chatsocket类的头文件开始处增加如下代码:class cchatclientdlg; /主对话框类 (6)给chatsocket类重载一个构造函数,其定义如下: cchatsocket:cchatsocket(cchatclientdlg* pdlg) m_pdlg = pdlg;并且在chatsocket类的cpp文件开始处增加如下语句:#includ
5、e chatclientdlg.h (7)通过classwizard响应类的chatsocket的onreceive函数,表示可以接收数据了,其代码如下:/通知客户端可以接受数据void cchatsocket:onreceive(int nerrorcode) csocket:onreceive(nerrorcode); if(m_pdlg) playsound(f:msg.wav,null,snd_async|snd_nodefault); m_pdlg-processpendingread(); (8)在主对话框chatclientdlg的头文件中定义chatsocket指针类型的私有成
6、员变量,其代码如下:cchatsocket* m_psocket;并且在cchatclientdlg类的头文件开始处增加如下代码:class cchatsocket;/基于csocket的新类cchatsocket (9)给对话框cchatclientdlg增加处理接收数据的共有成员函数processpendingread,其定义如下:void cchatclientdlg:processpendingread()/处理接收的数据 /定义缓冲区 char bufferbuffer_size; /接收数据 int nreceived = m_psocket-receive(buffer,buff
7、er_size,0); buffernreceived = 0; /将数据在列表框中显示出来 cstring str; str.format(%s,buffer); m_ctrlmsgs.addstring(str); (10)给对话框cchatclientdlg增加发送数据的私有成员函数sendmsg:/发送数据到服务器void cchatclientdlg:sendmsg(cstring strmsg) cstring str; str.format(%s:%s,m_strclientname,strmsg); m_psocket-send(str.getbuffer(0),str.get
8、length(),0);并且在cchatclientdlg类的头文件开始处定义缓冲区的大小,其代码如下:#definebuffer_size200 (11)给对话框cchatclientdlg增加表示聊天代号的cstring类型私有成员变量m_strclientname。 (12)在对话框cchatclientdlg的oninitialupdate函数中增加登录服务器的代码:bool cchatclientdlg:oninitdialog()/登录服务器 cdialog:oninitdialog(); assert(idm_aboutbox & 0xfff0) = idm_aboutbox);
9、 assert(idm_aboutbox appendmenu(mf_separator); psysmenu-appendmenu(mf_string,idm_aboutbox, straboutmenu); seticon(m_hicon, true);/ set big icon seticon(m_hicon, false);/ set small icon /显示登录对话框csetupdlg dlg; if(dlg.domodal()=idok) /创建一个新的socket m_psocket = new cchatsocket(this); if (!m_psocket-creat
10、e() delete m_psocket; m_psocket = null; afxmessagebox(create socket failed); return false; /连接服务器 while (!m_psocket-connect(dlg.m_strserver,dlg.m_nport + 700) if (afxmessagebox(failed to connect to serverntry again?,mb_yesno) = idno) delete m_psocket; m_psocket = null; return false; m_strclientname
11、= dlg.m_strname; else return false; /发送登录消息给服务器 sendmsg(进入聊天室); return true; / return true unless you set the focus to a control (13)给主对话框cchatclientdlg增加一个clistbox类型的变量m_strmsg。 (14)给住对话框cchatclientdlg增加一个输入发送信息的编辑框,并生成对应的cstring类型的变量m_strmsg。(15)给主对话框cchatclientdlg增加一个【send】按钮,其响应函数定义如下:void cchat
12、clientdlg:onsend() /响应控件send updatedata(true); sendmsg(m_strmsg);m_strmsg.empty();/清空编辑区 updatedata(false); (16)给主对话框增添一个【离开】按钮,其响应函数定义如下:void cchatclientdlg:leave()/离开 sendmsg(离开聊天室); m_ctrlmsgs.addstring(离开状态); m_psocket-close();(17)给主对话框增添一个【连接】按钮,其响应函数如下:void cchatclientdlg:land()/连接 oninitdialo
13、g();2.服务器端 (1)通过appwizard生成基于对话框的应用程序chatserver,在向导的第二步选择windowssockets的支持,其余步骤均用默认值。 (2)增加一个登录服务器的对话框资源,其id为idd_int,然后通过classwizard生成对应的基于cdialog的类cinitdlg。 (3)给对话框cinitdlg增加1个输入端口号的编辑框,并生成对应的整形变量m_nport。 (4)通过classwizard生成对应的基于csocket的类clisteningsocket,用来监听服务器。 (5)给clisteningsocket类声明一个主对话框cchatse
14、rverdlg指针类型的私有成员变量,其代码如下: protected: cchatserverdlg* m_pdlg;并且在clisteningsocket类的头文件开始处增加如下代码:class cchatserverdlg; /主对话框类 (6)给chatsocket类重载一个构造函数,其定义如下: cchatsocket:cclientsocket(cchatserverdlg* pdlg) m_pdlg = pdlg; 并且在clisteningsocket类的cpp文件开始处增加如下语句:#include chatserverdlg.h (7)通过classwizard响应类的cl
15、isteningsocket的onaccept函数,表示客户端连接,其代码如下:void clisteningsocket:onaccept(int nerrorcode) /通知服务器,有客户端需要连接服务器 csocket:onaccept(nerrorcode); /主对话框处理连接信息 if(m_pdlg) m_pdlg-processpendingaccept(); (8)通过classwizard生成基于csocket的新类cclientsocket,用来与客户端通信。(9)给cclientsocket类声明一个主对话框cchatserverdlg指针类型的私有成员变量,其代码如下
16、:protected: cchatserverdlg* m_pdlg;并且在cclientsocket类的头文件开始处增加如下语句:class cchatserverdlg;(10)给cclientsocket类重载一个构造函数,其定义如下:cclientsocket:cclientsocket(cchatserverdlg* pdlg)m_pdlg = pdlg;并且在cclientsocket类的cpp文件开始处增加如下语句:#include chatserverdlg.h(11)通过classwizard响应类的cclientsocket的onreceive函数,表示数据已到达,其代码如
17、下:void cclientsocket:onreceive(int nerrorcode) /通知服务器可以接受数据 csocket:onreceive(nerrorcode);if(m_pdlg) /让主对话框处理数据 m_pdlg-processpendingread(this); (12)在主对话框cchatserverdlg的头文件那个增加两个私有成员变量,其代码如下: clisteningsocket* m_psocket;/监听套节字 cptrlist m_connectionlist;/客户端套节字链表并且在cchatsvrdlg的头文件开始处增加如下代码:class clis
18、teningsocket;class cclientsocket;(13)给主对话框cchatsvrdlg增加处理客户端连接信息的私有成员变量processpendingaccept,其定义如下:void cchatserverdlg:processpendingaccept() /生成一个新的套节字与客户端通讯 cclientsocket* psocket = new cclientsocket(this); if (m_psocket-accept(*psocket) /将该套节字保存起来 m_connectionlist.addtail(psocket); else delete pso
19、cket;(14)给主对话框cchatsvrdlg增加更新所有客户端的私有成员函数updateclient,其定义如下:void cchatserverdlg:updateclients(char* buffer,int nbuffersize) for(position pos = m_connectionlist.getheadposition(); pos != null;) /将新信息发送给每个客户端cclientsocket* psocket= (cclientsocket*)m_connectionlist.getnext(pos);if (buffer != null)psock
20、et-send(buffer,nbuffersize,0); (15)给主对话框cchatsvrdlg增加接受数据的私有成processpendingre,其定义如下:void cchatserverdlg:processpendingread(cclientsocket* psocket) /定义缓冲区 char bufferbuffer_size; /接收数据 int nreceived = psocket-receive(buffer,buffer_size,0); buffernreceived = 0; /将数据在列表框中显示出来 m_ctrlmsgs.addstring(buffe
21、r);/将数据发送给每个客户 updateclients(buffer,nreceived);并且在cchatsvrdlg类的头文件开始处定义缓冲区的大小,其代码如下:#define buffer_size200(16)给主对话框cchatsvrdlg的oninitialupdate函数中显示初始化对话框,其定义如下:bool cchatserverdlg:oninitdialog() cdialog:oninitdialog(); assert(idm_aboutbox & 0xfff0) = idm_aboutbox); assert(idm_aboutbox appendmenu(mf_
22、separator); psysmenu-appendmenu(mf_string,idm_aboutbox, straboutmenu); seticon(m_hicon, true);/ set big iconseticon(m_hicon, false);/ set small icon/弹出初始话对话框cinitdlg dlg;if (dlg.domodal() = idok)/创建监听套节字m_psocket = new clisteningsocket(this);if (m_psocket-create(dlg.m_nport+700)if (m_psocket-listen(
23、)return true;elsereturn false;elsereturn false;return true; / return true unless you set the focus to a control五、运行结果如下: 1.服务端初始化, 进入聊天室界面:3.客户端初始化,端口号与服务器对应:4. 进入聊天界面:5.聊天室显示进入的客户:6.另一个客户进入聊天室:7.在客户界面上显示聊天界面: (芳菲燕)(卡罗)8.在聊天室界面上显示所有客户的聊天记录:9.显示芳菲燕离开聊天室:10.在芳菲燕的聊天界面上显示离开状态:11.显示芳菲燕又进入聊天室:六、课程设计心得:我做的
24、是“聊天室”系统,这个程序是和钟宏运同学合作的,他教会了我很多东西。通过做这个系统,我巩固和运用了很多课上学过的知识,也学会了很多课上没有讲过的知识,感受到了解课外知识的重要性,可谓是受益匪浅。在最开始建立工程时就犯了一个很大的错误,间错了工程,以致在建类时总是出错,浪费了几个小时才发现要建基于对话框的程序。这就体现了上课听讲的重要性,由于一时的疏忽又很有可能造成无可挽回的错误。我们做的系统很小,如果这是一个巨大工程,犯了这样一个错误,那是致命的。但是,话说回来,这不叫浪费时间,我们要吃一堑长一智,下次要记住,做工程,从第一步就应该认认真真,踏踏实实,避免出错。已进入工程,首先就做好了所有的界
25、面设计。其中又遇到了很多困难。在插入位图时,要调整位图的大小,这是我不知道的,通过参考书和讨论终于完成这一步。从中,我更加坚定了讨论的重要作用。其次,代码部分很多很复杂,但是结构确是很清晰的。我想这应该是mfc的一个很大的优点。根据参考书上的讲解和自己的揣摩,我明白了整个算法的灵魂。这个程序讲的是通信,互联网上关于聊天功能的工具非常多,但是其实现技术都是大同小异。我们做的这个系统是用winsock实现的最简单的聊天,多人能够发送信息至服务器,服务器首先显示进入聊天室的成员名,然后显示对方名字和聊天信息,而且可以并发执行。把通信的思想转化成语言的过程,靠的是c+的基础。实现过程中犯了很多错误,真
26、的很后悔基础功不牢固,现在就要付出更多的时间来弥补。最近有很多专业课的要做课程设计,每一次任务的完成,都会很有成就感,发现经验真的很宝贵。有些人,可以随口说出那些常用的函数,走了一条捷径,而不知道的人,就要花时间去找那个函数,或者说自己写代码来实现那个函数的功能。所以,从现在开始,我会认真面对每一次编程,即使是小程序,也一样能锻炼人。到这,这个学期的mfc学习结束了,但对知识的追求还没有结束,我们会的只是知识海洋里的一瓢水,还有更多的东西需要我们去钻研。不能说自己会有多高的觉悟,但小小的收益是无可否认的。最后,谢谢景老师本学期的精心教导!基于mfc的聊天室开发 这一贴发表一个基于mfc的聊天室
27、开发过程。 利用的机制主要是mfc的定时器加多线程编程。定时器主要是不断地显示消息,而多线程主要是不断地收发消息。刚开始做的时候时候,原本只想利用mfc的定 时器,因为在不带界面的的聊天室开发的时候,需要在主函数里面建立一个死循环,以保证主函数不回结束,从而才能保证线程的正常运行。而基于mfc界面开发 的则不一样。他不用建立死循环。但是紧随的一个问题也就出来了。当程序运行connect和recv函数的时候,整个程序就会陷入休眠,也就是说,这样的 一个利用定时器机制的程序,还是存在死锁。所以,本人还是在里面加入了多线程。但是,在双方建立连接的时候,本人还是没有使用多线程,因为觉得那样根本没 有必
28、要。开发过程如下(本人假设读者您已经熟悉mfc编程了):一,建立两个界面。 一个是server界面,一个是client界面。界面主要是两个文本域,一个主文本域,用来作为聊天记录的显示窗口,另一个是作为输入窗口。以级三个按钮,连接,发送,关闭,并将发送按钮设置为默认按钮。二,定义相应的变量和函数。在此本人只介绍server,因为client的与其大同小异。server需要为两个文本域定义控件型变量。本人如此定义:cedit m_mainmes;cedit m_mymes。然后,再在类向导中添加一个定时器ontimer,给连接按钮添加响应函数onbuttonconn();给发送按钮添加函数 onb
29、uttonsend() ;给关闭按钮添加函数onbuttonexit() 。client的添加过程除了类名不一样以外,其他的都一样。三,添加代码 在对话框的server工程的初始化函数cserverdlg:oninitdialog()中的return 前面添加如下代码:wsadata wsadata; word sockversion = makeword(2, 2); if( :wsastartup(sockversion, &wsadata) != 0) exit(0); / 创建原始套节字 sraw = socket(af_inet, sock_stream, ipproto_ip);
30、if(sraw=socket_error) m_mainmes.setsel(0,-1); m_mainmes.replacesel(套接字申请失败!); return 0; /填充地址结构 server.sin_family=af_inet; server.sin_port=htons(recv_port); server.sin_addr.s_un.s_addr=htonl(inaddr_any);/地址结构与套接字绑定 nret=bind(sraw,(struct sockaddr far *)&server,sizeof(server); if(nret=socket_error) /错误检测 m_mainmes.setsel(0,-1); m_mainmes.replacesel(绑定失败!); return 0; /设置监听 nret=listen(sraw,10); if(n
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 快思网幼儿园课件
- 玉溪师范学院《体操》2021-2022学年第一学期期末试卷
- 玉溪师范学院《社会统计学》2022-2023学年第一学期期末试卷
- 玉溪师范学院《马克思主义经典文献导读》2021-2022学年第一学期期末试卷
- 投影仪销售行业的成本核算-记账实操
- 某电商公司薪酬管理制度管理
- 2024年制造业统一数据管理方案-工控机操作系统备份与恢复
- 肿瘤患者营养教育
- 2024年耐高温涂料项目成效分析报告
- 2024年筒式采煤机项目评估分析报告
- 新课标人教统编版高中语文选择性必修中册第一单元全单元教案教学设计(含单元研习任务)
- GB/T 307.3-2017滚动轴承通用技术规则
- GB/T 20416-2006自然保护区生态旅游规划技术规程
- GB/T 20160-2006旋转电机绝缘电阻测试
- 第十七动物的采食量
- 女生生理卫生课-完整课件
- 2023学年完整版Unit7Willpeoplehaverobots教学反思
- 《森林生态学》课件第四章森林群落
- 国电南自-ps6000工程设计
- 部编版六年级上册第五单元写作《写感受最深的人或事》课件
- 五年级上册语文课件- 鸟的天堂 人教部编版(共39张PPT)
评论
0/150
提交评论