




已阅读5页,还剩63页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1 摘摘 要要 网络聊天室,其实质就是基于 internet 的一种网络聊天软件。它可以在网 络环境下进行实时的一对多或多对多的匿名交谈。网络聊天室软件的制作方法 有很多种,比如用 mfc 和 java 等语言设计的就有很多,本次课程设计主要是 利用 mfc 所提供的各种控件尤其是 winsock 控件,基于 c/s 模式,设计了一个 网络聊天室,圆满地实现在网络上实时聊天及多种人性化的辅助功能。 关键词:winsockwinsock;c/sc/s ;visualvisual c+c+ 6.06.0;聊天室聊天室 2 目录目录 .查找资料.4 1.1 网络聊天程序的开发背景 4 1.2 网络聊天程序的设计目标 4 .相关知识.5 2.1 winsock介绍 .5 2.2 mfc 的 casyncsocket类和 csocket类 .6 2.3 利用 csocket进行有连接的通信 8 2.4 方案比较与选 择 9 .详细设 计 .14 .1 聊天程序 现 .15 .程序流程图62 4.1 建立连接的流程图 .62 4.2 客户关闭或者注销时的程序流程图 .63 .程序运行结果64 5.1 客户端 .64 5.2 服务端 .64 、讨论及进一步研究建 议 65 、课程设计心得 66 、参考文 献 67 3 1.查找资料 当前是数字信息时代,网络时代,获得信息的渠道做种多样。而最为快速 的当然就是网络了。所以在课程设计动员之后,我们就马不停蹄的通过互联网 收缩有关网络编程和 mfc 编程的有关资料。找到大量资料之后,我们还有根据 课程设计的要求进行筛选资料,最后选定方案和确定实现方法。这也是我们第 一阶段的工作。 1.1 网络聊天程序的开发背景 近年来,互连网发展日新月异,网络使空间的距离不再成为人们沟通的障 碍,世界各个角落的人们可以通过 internet 收发邮件、实时聊天、获取最新的 资讯。所以网络聊天的程序早已被前人所实现,而且实现的方法多种多样。因 此,本次课程设计,我们主要借鉴前人创立的方法和编程经验来制作一个 c/s 聊天室程序,通过制作该程序达到的学习网络 socket 编程和使用 mfc 编程的相 关知识。 1.2 网络聊天程序的设计目标 本课题是设计一个网络聊天的程序,包括服务器端和客户端,主要功能为: 客户端部分: 、输入服务器端 ip 地址和端口号进行连接 、发送消息给服务器端并显示服务器端回传的消息 、在客户端增加历史聊天记录和当天聊天记录 、可以设置个性昵称、增添快捷表情、更换个性图像和背景设计 服务器端部分: 、立服务器端与客户端的连接请求 4 、接收所有用户发送的消息 、向所有在线用户群发消息 、在客户端增加历史聊天记录和当天聊天记录 、可以设置个性昵称、增添快捷表情、更换个性图像和背景设计 通过这次课程设计,可以比较深入的了解和掌握 winsock 控件基本属性、 方法和事件,熟悉 vc+的开发环境。理解网络聊天通信的概念,输控制协议 (tcp)进行数据交流,初步掌握网络聊天通信程序的设计方法,以及 windows 编程的一些方法。并能巩固和扩展之前学过的知识,进行项目的设计开发训练, 更好的适应社会的需求。 5 2.相关知识 2.1 winsock 介绍 windows sockets 规范以 u.c. berkeley 大学 bsd unix 中流行的 socket 接口为范例定义了一套 micosoft windows 下网络编程接口。它不仅包含了人们 所熟悉的 berkeley socket 风格的库函数;也包含了一组针对 windows 的扩展 库函数,以使程序员能充分地利用 windows 消息驱动机制进行编程。 windows sockets 规范本意在于提供给应用程序开发者一套简单的 api,并 让各家网络软件供应商共同遵守。此外,在一个特定版本 windows 的基础上, windows sockets 也定义了一个二进制接口(abi) ,以此来保证应用 windows sockets api 的应用程序能够在任何网络软件供应商的符合 windows sockets 协议的实现上工作。因此这份规范定义了应用程序开发者能够使用,并且网络 软件供应商能够实现的一套库函数调用和相关语义。 遵守这套 windows sockets 规范的网络软件,我们称之为 windows sockets 兼容的,而 windows sockets 兼容实现的提供者,我们称之为 windows sockets 提供者。一个网络软件供应商必须百分之百地实现 windows sockets 规范才能做到现 windows sockets 兼容。 任何能够与 windows sockets 兼容实现协同工作的应用程序就被认为是具 有 windows sockets 接口。我们称这种应用程序为 windows sockets 应用程序。 windows sockets 规范定义并记录了如何使用 api 与 internet 协议族 (ips,通常我们指的是 tcp/ip)连接,尤其要指出的是所有的 windows sockets 实现都支持流套接口和数据报套接口. 6 应用程序调用 windows sockets 的 api 实现相互之间的通讯。windows sockets 又利用下层的网络通讯协议功能和操作系统调用实现实际的通讯工作。 2.22.2 mfcmfc 的的 casyncsocketcasyncsocket 类和类和 csocketcsocket 类类 构造一个 casyncsocket 对象并使用该对象创建基础 socket 句柄。 套接字的创建:遵循两阶段构造的 mfc 模式。 例如: casyncsocket sock;sock.create( ); / use the default parameters - 或 - casyncsocket* psocket = new casyncsocket;int nport = 27; psocket- create( nport, sock_dgram ); 上面的第一个构造函数在堆栈上创建一个 casyncsocket 对象,第二个构 造函数在堆上创建 casyncsocket 。上面的第一个 create 调用使用默认参数 创建流式套接字,第二个 create 调用创建具有指定端口和地址的数据文报套 接字。 (任一个 create 版本都可以和任一种构造方法一起使用。 ) create 的参数有: “端口”:短整型。 对于服务器套接字,必须指定端口。对于客户端套接字,通常接受此参数 的默认值,该值允许 windows sockets 选择端口。 套接字类型: sock_stream (默认值)或 sock_dgram 。 套接字“地址” ,如“”或“” 。 该地址为 网络上的网际协议 (ip) 地址。很可能要始终依赖此参数的默认值。 如果套接字是客户端,则使用 casyncsocket:connect 将此套接字对 象连接到服务器套接字。 如果套接字是服务器,则将套接字设置为开始侦听 (使用 casyncsocket:listen)来自客户端的连接尝试。接收到连接请求时, 7 用 casyncsocket:accept 接受该请求。 接受连接后,可以执行验证密码等任务。 注意 accept 成员函数采用对新的空 csocket 对象的引用作为它的参数。 在调用 accept 之前,必须构造该对象。如果此套接字对象超出范围,则连接 关闭。不要对这个新套接字对象调用 create 。 通过调用 casyncsocket 对象的封装 windows sockets api 函数的成员 函数,与其他套接字进行通信。 如果在堆栈上创建了套接字对象,当包含函数超出范围时将调用此对象 的析构函数。如果使用 new 运算符在堆上创建了套接字对象,则您必须负责使 用 delete 运算符销毁此对象。 析构函数在销毁对象之前调用对象的 close 成员函数。 8 2.3 利用 csocket 进行有连接的通信 微软的 mfc 把复杂的 winsock api 函数封装到类里,这使得编写网络应用 程序更容易。casyncsocket 类逐个封装了 winsock api,为高级网络程序员 提 供了更加有力而灵活的方法。这个类基于程序员了解网络通讯的假设,目的是 为了在 mfc 中使用 winsock,程序员有责任处理诸如阻塞、字节顺序和在 unicode 与 mbcs 间转换字符的任务。 为了给程序员提供更方便的接口以自动处理这些任务,mfc 给出 了 csocket 类,这个类是由 casyncsocket 类继承下来的,它提供了比 casyncsocket 更高层的 winsock api 接口。csocket 类和 csocketfile 类可以 与 carchive 类一起合作来管理发送和接收的数据,这使管理数据收发更加便利。 csocket 对象提供阻塞模式,这对于 carchive 的同步操作是至关重要的。阻塞 函数(如 receive()、send()、receivefrom()、sendto() 和 accept())直到 操作完成后才返回控制权。 因此如果需要低层控制和高效率,就使用 casyncsock 类;如果需要方便, 则可使用 csocket 类。 由于我们对网络底层的了解比较浅薄,所以这次课程设计我们选择了采用 csocket 类来编程实现。下面主要针对这种方法进行讲述。 使用 csocket 对象涉及 carchive 和 csocketfile 类对象。以下介绍的针 对字节流型(即基于 tcp/ip 协议)套接字的操作步骤中,只有第 3 和第 4 步对于 客户端和服务端操作是不同的,其他步骤都相同。 构造一个 csocket 对象。 使用这个对象的 create()成员函数产生一个 socket 对象。在客户端 程序中,除非需要数据报套接字,create()函数一般情况下应该使用默认参 数。而对于服务端程序,必须在调用 create 时指定一个端口。需要注意的是, carchive 类对象不能与数据报(udp)套接字一起工作,因此对于数据报套接 字,casyncsocket 和 csocket 的使用方法是一样的。 如果是客户端套接字,则调用 casyncsocket connect()函数与服 务端套接字连接;如果是服务端套接字,则调用 casyncsocketlisten()开 始监听来自客户端的连接请求,收到连接请求后,调用 casyncsocketaccept()函数接受请求,建立连接。请注意 accept()成员 9 函数需要一个新的并且为空的 csocket 对象作为它的参数。 重载 csocket 类的部分函数。客户端需要重载 onreceive(int i) 和 onclose(int i);服务器端需要重载 onaccept(int i) 、onclose(int i) 和 onreceive(int i); 调用 send()的方法来发送数据,调用 receive()的方法来接受数据。 调用 close()方法来关闭套接字以终止通信。 通讯完毕后,销毁 csocket 对象。 2.42.4 方案比较与选择方案比较与选择 系统分析与设计系统分析与设计 1、系统构架方式如下图所示: 设计出一个完整的网络聊天程序,使之实现以上基本要求。 1、 服务端需要完成的三件事 1) 在特定端口等待连接请求,并需要维护一个客户连接表,已记录所 有成功连接。 2) 及时接受消息,然后转发到客户连接。 10 3) 监控连接状态,客户离开或故障时从列表中删除相应表项,并及时 更新连接表。 2、 客户端需要完成的三件事 1) 建立与维护服务器的连接,并随时监测连接状态。 2) 把用户输入的信息及时发送到服务端,同时准备好接受,并显示信 息。 3) 在用户退出时关闭连接。 程序方案程序方案比较:比较: 方案一:基于方案一:基于 tcptcp 的的 socketsocket 编程编程 tcp(transmission control protocol,传输控制协议)是基于连接的协 议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。 服务器端程序流程如下: 1) 创建套接字(socket) ; 2) 将套接字绑定到一个本地地址和端口上(bind) ; 3) 将套接字设为监听模式,准备接受客户请求(listen) ; 4) 等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应 于此次连接的套接字(accept) ; 5) 用返回的套接字和客户端进行通信(send/recv) ; 6) 返回,等待另一客户请求; 7) 关闭套接字; 客户端程序流程如下: 1) 创建套接字(socket) ; 2) 向服务器发出连接请求(connect) ; 3) 和服务器端进行通信(send/recv) ; 4) 关闭套接字。 在服务器端,当调用 accept 函数时,程序就会等待,等待客户调用 connect 函数发出连接请求,然后服务器端接受该请求,于是双方就建立了连 11 接。之后,服务器端和客户端就可以利用 send 和 recv 函数进行通信了。因为 服务器需要接受客户端的请求,所以必须告诉本地主机它打算在哪个 ip 地址和 哪个端口上等待客户要求,因此必须调用 bind 函数来实现这一功能。而对客户 端来说,当它发起连接请求,服务器端接受请求后,在服务端就保存了改客户 端的 ip 地址和端口的信息。这样,对服务器端来说,一旦建立连接之后,实际 上它已经保存了客户端的 ip 地址和端口号的信息,就可以利用所返回的套接字 调用 send/recv 函数与客户端进行通信。 程序流程图如下: 方案二:基于方案二:基于 udpudp(面向无连接)的(面向无连接)的 socketsocket 程序程序 udp(user data protocol,用户数据报协议)是与 tcp 相对应的协议。它 是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去。 udp 适用于一次只传送少量数据、对可靠性要求不高的应用环境 服务器端也叫接收端,对于基于 udp(面向无连接)的套接字编程来说, 它的服务器端和客户端这种概念不是很强化,我们也可以把服务器端,即先启 12 动的一端称为接收端,发送数据的一端称为发送端,也称为客户端。 服务端程序编写流程如下: 1) 创建套接字(socket) ; 2) 将套接字绑定到一个本地地址和端口上(bind) ; 3) 等待接受数据(recvfrom) ; 4) 关闭套接字。 虽然面向无连接的 socket 编程无须建立连接,但是为了完成这次通信,对 于接受端来说,它必须先启动以接受客户端发送的数据,因此接收端必须告诉 主机它是在哪个地址和端口上等待数据的到来,接收端(服务器端)必须调用 bind 函数将套接字绑定到一个本地地址和端口上。 客户端程序编写流程如下: 1) 创建套接字(socket) ; 2) 向服务器发送数据(sengto) ; 3) 关闭套接字。 在 udp 的套接字编程时,利用的是 sendto 和 recvfrom 这两个函数实现数 据的发送和接收,而基于 tcp 的套接字编程时,发送数据是调用 send 函数,接 受数据调用 recv 函数。 程序流程图如下: 13 方案比较结果方案比较结果 tcp 与 udp 最基本的区别在于基于连接与无连接,相比之下,第一种方案 对系统的要求以及数据量都比较大,但是保证数据的正确性与数据顺序,在传 输大量数据的时候具有更高的可靠性。至于第二种方案的优点在于传输的速度 快,程序结构精简。 总的来说,我认为 tcp 协议更能满足目前各行业对远程数据传输的要求,它提 供更稳定更便利的传输通道,满足了对安全性的要求以及远程数据传输的要求。 所以我们小组选择方案一。 14 3.3.详细设计详细设计 我们利用 mfc 提供的 csocket 类来编程实现一个网络聊天室。那么就需要一个聊天的 服务器(即是服务端) ,它可以和很多客户端进行通信,从而把来自不同的客户的聊天信息 转交到所有其他的客户端。当然也需要用户界面(客户端) 。这样就形成了一个采用 client/server 结构的并可以多人同时在线的聊天室。同时,服务器端应该有一定的管理 功能,如手动/自动响应申请、设置服务器名称和服务器端口、在线名单统计、单独断开某 人连接以及保持聊天记录等功能。对于客户端,因为是面向用户,所以外观和功能都应有 更高的要求。实现诸如:手动输入 ip 和用户名、头像切换、心情书写、表情输入、软件 皮肤切换、注销登录、保存聊天记录以及伸缩界面等功能。下面详细介绍各项功能是如何 15 实现的。 3.13.1 聊天程序的实现聊天程序的实现 (1)首先启动 visual c+ 6.0,利用 mfc appwizardexe建立一个新的 mfc 工程,工程名为 chat,在 mfc appwizard step1 的时候选择 dialog based 即基于对话框,在 step4 时勾选 windows sockets 选项(如图表 0-2) ,其他默 认值下一步。 图表 0-1 16 图表 0-2 (2)客户端的界面如图图表 0-3 所示。其中包含文档编辑框、按键控件、静 态文本控件组成。左半边由上自下分别是:头像、昵称、当天聊天信息显示、 12 个表情按钮、消息输入框和发送按钮。右半边有历史记录显示框、历史记录 显示按钮。 图表 0-3 软件界面 17 图表 0-4 控件类型及各自 id 标题控件类型控件 id 昵称: staticidc_static 服务器 ip: staticidc_static 端口号(默认 5000): staticidc_static 头像 buttonidc_touxiang 表情 1 buttonidc_bq1 表情 2 button idc_bq2 表情 3 button idc_bq3 表情 4 button idc_bq4 表情 5 button idc_bq5 表情 6 button idc_bq6 表情 7 button idc_bq7 表情 8 button idc_bq8 表情 9 button idc_bq9 表情 10 button idc_bq10 表情 11 button idc_bq11 表情 12 button idc_bq12 发送 button idc_send 连接 button idc_connect 建立 button idc_setserver 聊天纪录 button idc_liaotianjilu 聊天信息显示 editidc_showtext 信息输入 edit idc_inputtext 昵称输入 edit idc_name 服务器 ip 输入 edit idc_serverip 端口输入 edit idc_port 聊天记录显示 edit idc_showhistory 18 聊天程序总共有 6 个类。其中,cchatapp 和 caboutdlg 由 appwizard 实现;另 外,cserversocket 和 cclientsocket 分别负责服务端和客户端的网络通信功 能;cchatdlg 为程序的主控类,主界面、通信方式及程序逻辑均由该类实现, 它继承自 cdialog 类;cmessgage 是对消息的封装。 cclientsocketcclientsocket 通过相应的 onreceive 消息来接收数据,响应 onclose 消息来断开对话的 处理,实现以 carchive 对数据进行的串行化。 类定义代码如下: #include“messg.h“ /命令目标 class cchatdlg; class cclientsocket:public csocket public: carchive *m_asessionin; carchive *m_asessionout; csocketfile *m_sfsocketfile; cchatdlg *m_dlg; bool m_binit; /是否进行了初始化 bool m_bclose; /连接是否关闭 public: void init(cchatdlg *dlg); bool sendmessage(cmessg *msg); void closesocket(); public: static int getlocalhostname(cstring /获得本地 19 计算机名称 static int getipaddress(const cstring /获得本地 ip static int getipaddress(const cstring /获得 本地 ip static cstring errorreason(int tag); public: virtual void onreceive(int nerrorcode); virtual void onclose(int nerrorcode); public: cclientsocket(); virtual cclientsocket(); protected: ; cclientsocket.cppcclientsocket.cpp 中的代码:中的代码: #include “stdafx.h“ #include “chat.h“ #include “clientsocket.h“ #include“chatdlg.h“ / cclientsocket cclientsocket:cclientsocket() m_asessionin=null; m_asessionout=null; m_sfsocketfile=null; m_binit=false; 20 m_bclose=false; cclientsocket:cclientsocket() if(m_asessionin) delete m_asessionin; if(m_asessionout) delete m_asessionout; if(m_sfsocketfile) delete m_sfsocketfile; /clientsocket 成员函数 void cclientsocket:onreceive(int nerrorcode) csocket:onreceive(nerrorcode); /onreceive()函数的实现 do cmessg temp; temp.serialize(*m_asessionin); m_dlg-m_smsglist+=temp.m_strtext+“rn“; m_dlg-m_tmpmsglist=temp.m_strtext+“rn“; m_dlg-setdlgitemtext(idc_showtext,m_dlg-m_smsglist); file* fp; fp = fopen(“chatnote.txt“,“a+“); fputs(m_dlg-m_tmpmsglist,fp); fclose(fp); m_dlg-setdlgitemtext(idc_showtext,m_dlg-m_smsglist); int linenum=(cedit*) 21 (m_dlg-getdlgitem(idc_showtext)-getlinecount(); (cedit*) (m_dlg-getdlgitem(idc_showtext)- linescroll(linenum); if(!m_dlg-m_bclient) for(position pos=m_dlg- m_connectionlist.getheadposition(); pos!=null;) cclientsocket *t=(cclientsocket*) m_dlg- m_connectionlist.getnext(pos); if(t-m_hsocket!=this-m_hsocket) t-sendmessage( while(!m_asessionin-isbufferempty(); void cclientsocket:init(cchatdlg *dlg) m_sfsocketfile=new csocketfile(this); m_asessionin=new carchive(m_sfsocketfile,carchive:load); m_asessionout=new carchive(m_sfsocketfile,carchive:store); m_bclose=false; this-m_dlg=dlg; 22 /* *sendmessage()函数的实现 *主要功能: *将信息串行化 */ bool cclientsocket:sendmessage(cmessg *msg) if(m_asessionout!=null) msg-serialize(*m_asessionout); m_asessionout-flush(); return true; else m_bclose=true; /对方关闭了连接 closesocket(); m_dlg-closesessionsocket(); return false; /* *closesocket()函数的实现 *主要功能: *关闭套接字的连接 23 */ void cclientsocket:closesocket() if(m_asessionin) delete m_asessionin; m_asessionin=null; if(m_asessionout) delete m_asessionout; m_asessionout=null; if(m_sfsocketfile) delete m_sfsocketfile; m_sfsocketfile=null; close(); m_binit=false; m_bclose=true; /* *onclose()函数的实现 *主要功能: *关闭套接字的连接 */ void cclientsocket:onclose(int nerrorcode) 24 m_bclose=true; closesocket(); m_dlg-closesessionsocket(); csocket:onclose(nerrorcode); /* *getlocalhostname()函数的实现 *主要功能: *获得本地计算机的名称 */ int cclientsocket:getlocalhostname(cstring int nretcode; nretcode=gethostname(szhostname,sizeof(szhostname); if(nretcode!=0) /产生错误 shostname=_t(“没有取得“); return getlasterror(); shostname=szhostname; return 0; /* *getipaddress()函数的实现 *主要功能: *取得本地 ip 地址 */ int cclientsocket:getipaddress(const cstring if(lphostent=null) /产生错误 sipaddress=_t(“); return getlasterror(); lpstr lpaddr=lphostent-h_addr_list0; if(lpaddr) struct in_addr inaddr; memmove( sipaddress=inet_ntoa(inaddr); /转换为标准格式 if(sipaddress.isempty() sipaddress=_t(“没有取得“); return 0; /* * getipaddress ()函数的实现 *主要功能: *获得本地 ip 地址 */ int cclientsocket:getipaddress(const cstring if(lphostent=null) /产生错误 f0=f1=f2=f3=0; return getlasterror(); lpstr lpaddr=lphostent-h_addr_list0; /获取 ip if(lpaddr) struct in_addr inaddr; memmove( f0=inaddr.s_un.s_un_b.s_b1; f1=inaddr.s_un.s_un_b.s_b2; f2=inaddr.s_un.s_un_b.s_b3; f3=inaddr.s_un.s_un_b.s_b4; return 0; cstring cclientsocket:errorreason(int tag) /错误信息的宏定义 cstring result; switch(tag) case wsanotinitialised: result=“a successful afxsocketinit must occur before using this api.“; break; 27 case wsaenetdown: result=“the network subsystem failed“; break; case wsaeaddrinuse: result=“the specified address is already in use“; break; case wsaeinprogress: result=“a blocking windows socket call is in progress“; break; case wsaeaddrnotavail: result=“the specified address is not available from the local machine“; break; case wsaeafnosupport: result=“address in the specified family cannot be used with this socket“; break; case wsaeconnrefused: result=“the attempt to connect eas rejected“; break; case wsaedestaddrreq: result=“a destination address is requireed“; break; case wsaefault: result=“the nsockaddrlen arguement is incorrect“; break; case wsaeinval: result=“invalid host address“; break; 28 case wsaeisconn: result=“the socket is already connected“; break; case wsaemfile: result=“no more file descriptions are available“; break; case wsaenetunreach: result=“the network cannot be reached from this host at this time“; break; case wsaenobufs: result=“no buffer space is available.the socket cannot be connected“; break; case wsaenotsock: result=“the descriptor is not a socket“; break; case wsaetimedout: result=“attempt to connect timed out without establishing a connection“; break; case wsaewouldblock: result=“the socket is marked as nonblocking and the connnection cannot be completed immediately“; break; default: result=“unknown error“; return result; 29 cserversocketcserversocket cserversocket 主要功能是实现 onaccept()消息,负责监听服务窗口,是 一个服务 socket。 cserversocket.h 的代码如下: / cserversocket command target class cchatdlg; class cserversocket: public csocket public: cserversocket(); virtual cserversocket(); cchatdlg *m_dlg; uint m_uport; bool init(uint port,cchatdlg *dlg); public: virtual void onaccept(int nerrorcode); /用于响应 onaccept 消 息的函数 ; cserversocket.cppcserversocket.cpp 的代码如下:的代码如下: #include “stdafx.h“ #include “chat.h“ #include “serversocket.h“ #include “chatdlg.h“ 30 / cserversocket cserversocket:cserversocket() cserversocket:cserversocket() /cserversocket 成员函数 bool cserversocket:init(uint port,cchatdlg *dlg) m_uport=port; m_dlg=dlg; if(create(m_uport)=false) afxmessagebox(_t(“server socket create error“); return false; if(this-listen()=false) afxmessagebox(“server listen error“); return false; m_dlg-setdlgitemtext(idc_showtext,“serverr has been set ok!“); return true; void cserversocket:onaccept(int nerrorcode) 31 m_dlg-processpendingaccept(); csocket:onaccept(nerrorcode); cmessgcmessg cmessg 类主要作用是实现信息的串行化,方便信息的传输。 cmessg.h 代码如下: #pragma once class cmessg:public cobject /命令目标 protected: declare_dyncreate(cmessg) public: cmessg(); public: cstring m_strtext; public: void init(); public: virtual cmessg(); virtual void serialize(carchive /实行串行化 #if def_debug virtual void assertvalid() const; virtual void dump(cdumpcontext #endif ; 32 cmessg.cppcmessg.cpp 代码如下:代码如下: #include “stdafx.h“ #include “chat.h“ #include “messg.h“ / construction/destruction implement_dyncreate(cmessg,cobject) cmessg:cmessg() init(); cmessg:cmessg() /cmessg 成员函数 void cmessg:init() m_strtext = _t(“); /cmsg serialization void cmessg:serialize(carchive /cmsg diagnostics #if def_debug void cmessg:assertvalid() const cobject:assertvalid(); void cmessg:dump(cdumpcontext #endif cchatdlgcchatdlg cchatdlg 类负责调度整个工程,实现界面消息的添加与响应,组织整个工 程的运行。 1) 程序开始运行,进行对话框的初始化是在 oninitdialog()函数中实现 的,在开始的时候自动获得本地机器的 ip 地址并显示在 ip address control 控件中。 2) 连接服务器按钮消息的响应函数。完成服务器的连接,调用 cclientsocket 类的 connect 函数来实现,同时对连接返回的信息进行 处理。 3) 建立服务器按钮信息的响应函数。 4) 发送按钮消息的响应函数。读取文本框中的信息,调用 cmessg 类的函 数以实现信息的串行化,然后再调用 cclientsocket 类的 34 sendmessage()函数将信息发送给建立连接的对方。 chatdlg.h 代码如下: / cchatdlg dialog #include “clientsocket.h“ #include “serversocket.h“ /cchatdlg 对话框 class cchatdlg : public cdialog /构造 public: cchatdlg(cwnd* pparent = null); /标准构造函数 /对话框数据 enumidd=idd_chat_dialog; protected: virtual void dodataexchange(cdataexchange *pdx); protected: hicon m_hicon; /生成的消息映射函数 virtual bool oninitdialog(); afx_msg void onsyscommand(uint nid,lparam lparam); afx_msg void onpaint(); /afx_msg void oninputtext(); afx_msg hcursor onquerydragicon(); declare_message_map() public: cstring m_sinputtext; public: cstring name; public: cstring m_sshowstring; public: 35 uint m_uport; /添加的变量 public: bool m_binit; bool m_bclient; cclientsocket m_clientsocket; cserversocket m_plistensocket; cptrlist m_connectionlist; cstring m_smsglist; cstring m_tmpmsglist; public: void processpendingaccept(); void closesessionsocket(); void clearcontent(); void onclearconnection(); public: afx_msg void onbnclickedconnect(); public: afx_msg void onbnclickedsetserver(); public: afx_msg void onbnclickedbutton1(); ; cchatdlg.cppcchatdlg.cpp 代码如下:代码如下: #include “stdafx.h“ #include “chat.h“ #include “chatdlg.h“ 36 #ifdef
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2030年中国镁锰电池市场规模分析及发展建议研究报告
- 2025-2030年中国辣椒制品行业运行动态与投资战略研究报告
- 2025-2030年中国蒿甲醚行业市场现状调研与前景规模预测报告
- 2025-2030年中国自动高压蒸汽灭菌器市场发展状况及前景趋势分析报告
- 2025-2030年中国育发水市场发展状况及投资规划研究报告
- 2025安全员-C证考试题库
- 2025-2030年中国糯玉米汁饮料市场发展预测及前景调研分析报告
- 2025-2030年中国粉针类头孢制剂行业需求分析与十三五规划研究报告
- 2025-2030年中国移动电源车产业运行动态及前景趋势预测报告
- 2025-2030年中国石棉板行业运行态势及投资战略研究报告
- 承包商入厂安全培训试题附参考答案【完整版】
- 四川省公务员考试行测真题
- 2024年广东省初中学业水平考试中考英语试卷(真题+答案解析)
- DL-T-255-2012燃煤电厂能耗状况评价技术规范
- 家庭教育家长会教案及反思(3篇模板)
- 职业培训师三级操作技能鉴定卷库及答案
- 【视频号运营】视频号运营108招
- 新能源客车安全应急处理指南
- (正式版)JTT 421-2024 港口固定式起重机安全要求
- 地连墙施工MJS工法桩施工方案
- 《电力建设施工技术规范 第2部分:锅炉机组》DLT 5190.2
评论
0/150
提交评论