下载

1下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 基于VC的局域网聊天室

基于VC的局域网聊天室.doc

基于VC的局域网聊天室

生态健康
2012-05-24 0人阅读 举报 0 0 暂无简介

简介:本文档为《基于VC的局域网聊天室doc》,可适用于高等教育领域

武汉理工大学毕业设计(论文)目录I摘要AbstractII绪论论文的目的和意义论文的主要内容国内外聊天系统的现状开发环境及编程语言介绍VisualC可视化集成开发环境网络编程局域网聊天室的设计客户机服务器模式系统实现原理系统工作流程界面设计局域网聊天室的实现准备工作功能实现结论参考文献附录致谢摘要随着计算机科学和Internet的飞速发展,网上聊天已成为人们相互交流的一种方式,与Email、电话相比,聊天服务更具有实时性和有效性。本项目采用软件工程的方法综合运用程序设计技术、网络技术以VisualC作为系统前台应用程序开发工具主要研究了在TCPIP协议下的局域网聊天室。此局域网聊天室采用客户端服务器(CS)模式和TCP连接。它有两个模块组成:服务器和客户端。服务器模块主要用来维护网络上所有用户的信息如用户名聊天客户端模块主要包括用户登录、发送信息、接收信息等。整个工程采用结构化的方式进行编译逐步完善系统功能。系统采用CSocket实现连网功能。CSocket是MFC在CAsyncSocket基础上派生的一个同步阻塞Socket的封装类。而Socket是Windows中得到广泛应用的、开放的、支持多协议的网络编程接口。该聊天室是一套适用于Internet网络使用的网络聊天室其操作简单灵活性好运行也比较稳定。关键词:VC套接字传输控制协议网络聊天室AbstractAlongwiththehighspeeddevelopmentofthecomputerscienceandInternet,chattingonlinehasbeenanimportantmethodinourcommunicationComparingwithEmailandtelephone,thechatlineserviceismorerealtimeandeffectiveThesubjectunderdiscussionadoptsthemethodofthesoftwareproject,useproceduredesigningtechniqueandthenetworktechnologyTheprojectuseVisualCasthedevelopmenttools,mainlystudiesundertheTCPIPprotocolofLANchatroomsThislocalareanetworkchattooladoptsclientservermechanism(CS)andTCPItiscomposedoftwocomponents:theserverandtheclientTheservermodelismainlyusedtoprootectallusers’information,incuudinguser’snameandsoonTheclientmodelincludesuserregediting,,sendingmessage,receivingmessageandsoonSystemusesCSockettoachievenetworkingCSocketisasynchronousblockingSocketwrappersderivedbyMFCbasedonCAsynncSocketTheSocketiswidelyusedforopen,multiprotocolnetworkprogramminginterfaceinwindowsThisnetworkchattoolcanbeusedininternetenvironment,itcanbeoperatedsimply,itsflexibilityisfineandcanrunsteadilyKeyWords:VCCSocketTCPNetworkChatroom绪论在网络越来越发达的今天人们对网络的依赖越来越多越来越离不开网络由此而产生的聊天工具越来越多例如国外的ICQ、国内腾讯公司开发的OICQ。基于VC网络编程的强大功能本次毕业设计使用VC编写一个聊天系统。本系统建立在VC平台上系统的设计使用了面向对象技术和面向对象的设计原则。系统采用CS结构客户端与客户端以及客户端与服务器端之间通过CSocket传送消息。使用VC语言编写开发工具采用VC。论文的目的和意义近年来随着全球信息化的不断发展网络也在飞速发展。出于高效、快速地处理各种事务的目的越来越多的企业在其内部使用局域网来进行工作。在内部局域网的帮助下企业得以简化信息流程提高信息交换的速度从而提高工作效率。然而随着企业规模的扩大业务量的增加企业内部的信息越来越私密企业只希望员工通过内部局域网进行沟通与交流避免企业内部机密通过Internet泄露到外部。为了解决上述矛盾人们提出了开发局域网聊天软件的构想通过局域网聊天软件企业员工可以随时的进行即时消息传递召开网络会议等有利于提高工作效率同时又保护了企业内部信息的安全。随着用户对软件功能的需求不断提高,即时通讯的产品也不断地更新换代。即时通讯的发展不论是在基础应用方面还是在扩展应用方面都有着飞跃。为了满足用户的需求包括腾讯公司的聊天软件QQ在内许多即时性聊天工具都推出了语音聊天、视频聊天功能模块。本课题研究的是基于局域网的聊天室用VC编写的程序程序实现一般的文字聊天功能可作为某局域网的交流工具。本系统采用基于Socket的方法实现局域网通信基于Socket的局域网通信软件可以为企业原有的局域网提供一种良好安全快速的通信机制。它的实现无需对企业原有的局域网硬件进行任何改动具有实现成本低廉的优点它的使用能有效地降低局域网通信负荷提高局域网的使用效率可以很好地解决企业内部局域网的各种通信需求。基于Socket的局域网聊天工具很好地诠释了Socket通信的原理并且在企业内部通信、教学、讨论等应用中都具有一定的实用价值。它具有信息收发速度快保密性好占用网络带宽资源低占用服务器吞吐能力低易于编程实现等优点。基于Socket的局域网通信软件应用范围广阔不但可以处理传统的通信需求而且也能扩展以适应新型的网络应用如网络教育数据影音传输等拥有广泛的应用前景。如今基于局域网的即时通信工具一般采用UDP或者TCP协议体系来实现开发技术已经比较成熟。UDP的实时性比较好但是不一定提供可靠的数据传输TCP可以提供可靠的数据传输本课题采用TCP完成局域网聊天室的设计。论文的主要内容本课题主要研究的是局域网聊天室该聊天室采用客户端服务器(CS)模式和TCP连接能实现用户在客户端与服务器间传递文字信息。它有两个程序组成:服务器和客户端首先需要登录服务器需要指定服务器地址和端口号同时设置一个网名与服务器建立连接如果所取网名已经被其他已经登录的客户端使用服务器会告诉客户端要求重新登录。登录后客户端各用户可以发送文字信息相互聊天。服务器模块主要用来维护网络上所有用户的信息如用户名聊天客户端模块主要包括用户登录、发送信息、接收信息等。整个工程采用结构化的方式进行编译逐步完善系统功能。研究本课题需要熟练掌握VC语言并且熟悉VC平台的操作利用socket编程技术、TCP协议进行局域网聊天软件的实际开发。选择TCP协议而不选UDP是为了保证信息的可靠性不同于UDP协议TCP要求在获得可靠连接后才发送消息。第一章主要讨论课题研究的目的和意义并对主要内容作了简单的介绍。第二章介绍了目前国内外聊天系统的现状对国内QQ和国外MSN聊天软件做出了概括性的介绍并作了一些比较。第三章主要介绍开发平台和网络编程对Socket的历史和发展简单描述。第四章讨论了整个聊天系统的设计介绍了客户端服务器模型并讨论了系统的实现原理和界面设计。第五章主要是对各个功能的实现做了详细的分析第六章给出总结对设计过程中出现的问题进行分析概括了整个聊天室系统的优缺点。并对今后的继续完善做了展望!国内外聊天系统的现状目前国内外做聊天系统的公司很多产品也琳琅满目国内有诸如腾讯QQ、新浪UC、网易泡泡等国外有著名的MSN(新版改名为LiveMessenger)以及跨平台Gaim等。本人取最具代表性的QQ和MSN进行了一些研究作为开发聊天系统的准备。腾讯无疑是国内即时通讯市场的霸主自从年进入即时通讯领域并迅速占市场之后其在国内用户数量始终高居榜首即使近几年面对微软MSN的强大攻势腾讯QQ的时常占有率依然稳步增长。腾讯的成功与其对QQ的不断创新和完善是分不开的。参考了许多网络上的资料以及自己通过观察腾讯QQ运行时的各种细节。可以确定腾讯QQ是以多服务器提供服务、服务器总控客户端、客户端之间UDP直连通信的。并且在两个客户端之间不能建立直连的情况下才由服务器进行中转通信。图腾讯QQ服务器客户端模型与腾讯QQ不同微软的MSNMessenger只使用了TCP作为传输层通信协议所有客户端与服务器进行连接然后通过与服务器的TCP连接进行中转通信。图MSN服务器客户端模型腾讯使用的模型中服务器主要处理客户端各种状态的控制可以极大减轻服务器的处理压力但其内部协议和实现复杂度都较高。而MSNMessenger所有数据都要经过服务器服务器压力可想而知(难怪平时很少见到使用MSN进行语音视频聊天的)。上述软件都实现了广域网上的即时通信在使用方面各有特色在实现方面也各有所长。但是随着企业规模的扩大业务量的增加企业内部的信息越来越私密企业只希望员工通过内部局域网进行沟通与交流避免企业内部机密通过Internet泄露到外部所以局域网的聊天工具也占了很大的市场。开发环境及编程语言介绍VisualC可视化集成开发环境VC是微软推出的一款可视化编程工具适用面非常广泛。VC包含了一个文本编辑器、资源编辑器、工程编译工具、一个增量连接器、源代码浏览器、集成调试工具以及一套联机文档。使用VC可以完成创建、调试、修改应用程序等的各种操作。VC采用标准的多窗口Windows用户界面并增加了一些新特性使得开发环境更易于使用用户很容易学会它的使用方法。由于VC是一个可视化的开发工具在介绍VC的各个组成部分之前首先了解一下可视化编程的概念。可视化技术是当前发展迅速并引人注目的技术之一它的特点是把原来抽象的数字、表格、功能逻辑等用直观的图形、图象的形式表现出来。可视化编程是它的重要应用之一。所谓可视化编程就是指:在软件开发过程中用直观的具有一定含义的图标按钮、图形化的对象取代原来手工的抽象的编辑、运行、浏览操作软件开发过程表现为鼠标点击按钮和拖放图形化的对象以及指定对象的属性、行为的过程。这种可视化的编程方法易学易用而且大大提高了工作效率。网络编程年代初美国政府的高级研究工程机构(ARPA)给加利福尼亚大Berkeley分校提供了资金让他们在UNIX操作系统下实现TCPIP协议。在这个项目中研究人员为TCPIP网络通信开发了一个API(应用程序接口)。这个API称为Socket接口(套接字)。今天SOCKET接口是TCPIP网络最为通用的API也是INTERNET上进行应用开发最为通用的API。套接字是从英文单词socket翻译过来的,(Socket在英文中是插座的意思,在这里设计者实际上是暗指电话插座。因为在Socket环境下编程很像是打电话的模拟,Internet的IP地址就是电话号码,要打电话,首先要有个电话插座,在程序中就是向系统申请一个Socket,以后两台机器上的程序“交谈”都是通过这个Socket来进行的。对程序员来说,也可以把Socket看成一个文件指针,只要向指针所指的文件读写数据,就可以实现双向通讯。它是网络通信的基本构件。套接字是可以被命名和寻址的通信端点,是网络互连终点。换句话说,网络互连是两个计算机或处理器通过网络相互传输数据。网络专业人员将每个网络会话的末端称做终点。若通过套接字接口进行网络互连,则程序在每个网络互连的末端都需要一个套接字,套接字接口相当于文件系统,可以使用API通过网络软件申请一个可以指定特定套接字的句柄来定义套接字的特性。当然,套接字句柄和文件句柄是不同的,文件句柄指向一个特定的文件和设备,而套接字句柄并不代表一个特定的终点或目标地址。基于套接字的程序先创建一个套接字,然后再将套接字和目标终点连接起来。底层的套接字函数是WinInetAPI的一部分,但使用MFC的CSocket类,它封装了这些套接字函数。CSocket类实际上来源于CAsyncSocket类,但该类编程比较复杂,需要编写底层函数来进行通信操作,而CSocket为底层函数提供了一个更抽象的封装,替编程者执行对底层函数的操作,简化了Socket编程。CSocket类提供了一个高级的Socket支持,运用了MFC的序列化类来提供和传输Socket对象。利用Socket进行通讯,有两种主要的方式。一种叫流方式(StreamSocket)也称面向连接方式。在这种方式下,两个通讯的应用程序之间先要建立一种虚拟的连接。其过程好像客户机在给服务器打电话,只有服务器拿起了听筒,才有可能开始传输数据,这种方式对应的TCP协议。第二种叫作数据报文方式(DatagramSocket),又称无连接方式,这时两台计算机像是把数据放在一封封信里通过网络寄给对方,信在传送的过程中有可能会残缺不全,而且,后发出的信也有可能会先收到,它对应的是UDP协议。流方式的特点是,通讯可靠,对数据有校验和重发的机制,通常用来作数据文件的传输如ftp、telnet等数据报文方式由于取消了重发校验机制,能够达到较高的通讯速率,可以用作一些对数据可靠性要求不高的通讯,如实时的语音、像转送、播消息等。由于两台计算机之间采用的是客户机服务器模式,为保证数据的可靠性,可以采用了基于流方式的套接字编程。局域网聊天室的设计客户机服务器模式通信的两个应用程序间相互作用的主要模式是客户机服务器模式,即客户向服务器发出服务请求,服务器接收到请求后,提供相应的服务。客户机服务器模式的建立基于以下两点:首先。建立网络的起因是网络中软硬件资源、运算能力和信息不均等,需要共享,从而造就拥有众多资源的主机提供服务,资源较少的客户请求服务这一非对等作用。其次,网间进程通信完全是异步的,相互通信的进程间既不存在父子关系,又不共享内存缓冲区,因此需要一种机制为希望通信的进程间建立联系,为二者的数据交换提供同步。客户机服务器模式在操作过程中采取的是主动请求方式:首先服务器方要先启动,并根据请求提供相应服务:)打开通信通道并告知本地主机,它愿意在某一公认地址上接收客户请求)等待客户请求到达该端口)接收到服务请求,处理该请求并发送应答信号。服务完成后,关闭与客户的通信链路,并终止)返回第二步,等待客户请求)关闭服务器。客户方:)打开一通信通道,并连接到服务器所在主机的特定端口)向服务器发服务请求,等待并接收应答)请求结束后关闭通信通道并终止。由此可知:)客户与服务器进程的作用是非对称的,因此编码不同)服务进程一般是先于客户请求而启动的。只要系统运行,该服务进程一直存在,直到正常终止或被强迫终止。系统实现原理聊天系统的设计跟普通网站设计有着许多不同的地方普通网站设计所考虑的因素例如普通网站需要对布局进入大量美化以及动画设计等等而聊天室只要提供满足访客双方直接实时聊天即可。因此在设计聊天系统的过程中必须要考虑好以下几个设计要点:在Internet上的聊天程序一般都是以服务器提供服务端连接响应使用者通过客户端程序登录到服务器就可以与登录在同一服务器上的用户交谈这是一个面向连接的通信过程。因此程序要在TCPIP环境下实现服务器端和客户端两部分程序。为了利用重载套接字的消息相应函数必须从CAsyncSocket派生出自己的套接字类,有时为了分开监听套接字和客户端套接字,还应该分别派生监听套接字类和客户端套接字类。利用这两类函数就可以开始写网络通信程序。整个过程可以分成三个阶段连接建立、数据传和拆除连接。图系统实现原理图在套接字创建以及通信的过程中将用到很多函数处理相关事件具体函数见下:()AfxSocketInit():此函数在初始化应用程序函数中调用用于确定Winsock版本并做一些套接字的初始化工作。()Create():创建套接字在创建监听套接字时必须加上端口号。()Listen():监听套接字专用用于向监听套接字发送对端口监听的命令。()Connect():客户端套接字专用用于向服务器发送连接请求。()Accept():监听套接字专用用于接受客户端通过网络发送的连接请求建立连接。()Send():用于向套接字发送数据。()Receive():用于套接字接受数据。()Close():关闭套接字可由析构函数调用。在整个通信过程中当某一事件触发时应用框架将收到某些消息从而自动调用响应函数。可以在这些函数中写入自己的代码从而更好的完成通信过程。具体函数见下:()OnAccept():监听套接字在端口听到连接请求时应用程序框架自动调用以告知可以接受请求或拒绝连接。可在该函数中调用Accept()来连接请求建立连接。()OnConnect():当客户端套接字连接请求完成后,应用程序框架调用该函数,告之是否成功。()OnSend():框架调用此函数来通知该套接字现在可以调用Send函数来传送数据。()OnReceive():框架调用此函数来告诉套接字现在可以调用Receive函数从数据缓冲区取出数据。()OnCloes():框架调用该函数告知套接字与其连接的对方套接字已经断开连接。系统工作流程图系统总工作流程图首先启动聊天室的服务端设置端口打开监听。然后启动客户端(可启动多个)设置用户昵称和连接端口等信息连接服务器。进入聊天室后用户之间可以进行简单的文字聊天。当用户发送信息后服务器会收到用户发送的信息然后服务器把收到的信息发送给所有在线用户。这样登入服务器的用户们之间就可以进行简单的文字聊天了。当用户进入聊天室后服务器会发送相应的消息通知该用户进入了聊天室。当用户断开连接后服务器也会通知该用户下线。整个聊天室基于CSocket的流式连接放大。基于TCP传送控制协议。该协议所要求用户必须先确定连接成功后才能发送消息如果是UDP协议那可以不进行连接过程这样实时性比较好。界面设计图界面资源图在设计的过程中当掌握了核心思想内容成功完成功能实现后界面设计永远是重要的部分。一个好的界面会让使用者方便操控会让功能直观的实现也会给人们良好的视觉冲击。上图为该局域网聊天室的服务器界面资源图。对于基本内容发送及接受消息设计都以比较突出的方式显示并且占据大部分界面。上半部为服务器名称设置监听端口的设置。右边部分为一些其它内容设置。局域网聊天室的实现准备工作图设置MFC向导图该聊天室是基于MFC的CSocket编程首先建立正确的MFCAppWizard(exe)程序后进行MFC程序向导的设置中要记得勾选WindowsSocket这项。这样编译器会自动的加载有关Socket的相关动态连接库和静态库及相应的头文件到程序中。如果没有勾选也没关系只要在编程过程中正确加入相应内容即可!正确的向导设置会给你省去很多工作!在开始程序之前先得创建一个派生于CAsyncSocket的类当然也可以直接派生于CSocket。CAsyncSocket类中封装了一些有关套接字之间消息传递的函数。当有相关消息到来时应用框架会自动调用这些函数从而可以比较方便的实现套接字之间的信息传输。代码如下:classcsocket:publicCSocket{public:voidOnReceive(inti){dlg>onrev(mynum)}voidOnAccept(inti){dlg>onac()}voidOnClose(inti){dlg>oncl()}voidsetp(CTcpseverDlg*severdlg,intnum){mynum=numdlg=severdlg}private:CTcpseverDlg*dlgintmynum}在上面的代码中只解释一个封装于CAsyncSocket中的函数。OnReceive()函数在MSDN中的声明是这样的:virtualvoidOnReceive(intnErrorCode)该函数定义为虚函数这样才可以在派生的新类csocket中重新定义根据多态性原理可以当应用程序框架收到消息后会调用定义的这个OnReceive函数。在函数的实现中加入了自己的代码:dlg>onrev(mynum)该代码意为用对象dlg调用函数onrev()onrev()在类CTcpseverDlg中做了声明和定义后续会去分析这个函数。在类csocket中直接用到了CTcpseverDlg类的对象。这样在派生csocket类之前一定要对CTcpseverDlg类做一个申明。或者把类csocket类的声明放在类CTcpseverDlg之后。当服务器收到网络发送的消息后框架自动调用函数OnReceive()这样就执行了代码dlg>onrev(mynum)现在来分析onrev()在类CTcpseverDlg中的定义。voidCTcpseverDlg::onrev(intmynum){CStringstr,strinticharssfor(intj=j<j)ssj=''csrevmynumReceive(ss,)strFormat("s",ss)for(i=i<=csnumi)if(csrevi)csreviSend(str,)GetDlgItemText(IDCEDIT,str)str=str"rn"strSetDlgItemText(IDCEDIT,str)CEdit*ce=((CEdit*)GetDlgItem(IDCEDIT))ce>LineScroll(ce>GetLineCount())}从定义中可以看出函数实现的功能是把收到的信息(某客户端发送的)发送到连接到这个聊天室的所有用户。并且在发送完成后把信息打印到自己的屏幕上。并设置正确的滚动条信息。这样就完成了接收并转发消息的功能。下面的OnAccept和OnClose函数都是框架自动调用的分别在建立连接和断开连接后触发调用。在这些消息调用中只要正确的加入自己的信息就可以处理好各种事件。函数setp()起到了一个指针保护作用。在类CTcpseverApp的初始化函数中对套接字做了一个初始化工作使工程正确的得到WinSock的信息。部分代码如下:if(!AfxSocketInit()){AfxMessageBox(IDPSOCKETSINITFAILED)returnFALSE}AfxSocketInit()函数如果初始化成功则返回非零否者返回零。这样可知如果初始化失败则会调用函数AfxMessageBox弹出错误信息。在类CTcpseverDlg的初始化函数中也做了一些事情看代码:BOOLCTcpseverDlg::OnInitDialog(){CWnd*wndCStringstrwnd=GetDlgItem(IDCMARKST)wnd>GetWindowText(str)wnd=GetDlgItem(IDCMARK)wnd>SetWindowText(str)wnd>ShowWindow(SWHIDE)SetDlgItemText(IDCEDIT,"亡羊哺狼")SetDlgItemText(IDCEDIT,"")CBitmapbitmapbitmapLoadBitmap(IDBBITMAP)msetPicModifyStyle(,SSBITMAP)msetPicSetBitmap((HBITMAP)bitmapDetach())returnTRUEreturnTRUEunlessyousetthefocustoacontrol}代码中又涉及到了虚函数多态性实现了动态联编。先定义了个CWnd的指针。CWnd封装了函数GetDlgItem()这样对于其派生的比如编辑框类静态文本类按钮类等都继承了此函数。这样只需在最前面定义一个CWnd的指针就可以动态的获取相应消息。这些代码首先对窗口进行了一些文本设置和某些窗口的隐藏。还设置了服务器的昵称为"亡羊哺狼"默认监听端口号并且对某窗口的位图做了个默认的设置。功能实现图服务器启动界面图运行VC打开服务端时启动界面如上。首先服务器有一个默认设置服务器名称默认值为“亡羊哺狼”默认端口号是注意了在位机器上端口号有个。但是被系统占用了只能设置从中的号码。当点击开始监听后服务器设置中的按钮都会变成灰色不可点击了这样在整个监听过程中维护了信息的安全性。聊天区右上角有个“清空”按钮初始状态是灰色的不可点击。当聊天区有信息记录后会变成可点击按钮。当点击清空后会清空聊天区的信息记录。监听成功用户登入聊天内容用户退出等信息都会记录在聊天区中方便阅读。在监听端口过程中可能发生端口被占用的错误信息这样就得重新设置端口了。当然从之间的端口不可能被全部占用。下面贴出部分实现代码:voidCTcpseverDlg::Onsend(){CStringstr,historyGetDlgItemText(IDCEDIT,history)GetDlgItemText(IDCEDIT,str)str=severname":"strintlen=strGetLength()for(inti=i<=csnumi){if(csrevi){if(sended=csreviSend(str,len)){SetDlgItemText(IDCEDIT,"")SetDlgItemText(IDCEDIT,history"rn"str)CEdit*ce=((CEdit*)GetDlgItem(IDCEDIT))ce>LineScroll(ce>GetLineCount())}}}}这是点击控件“发送”的消息响应函数。函数先把以前聊天区的内容存储下来再把其要发送的内和以前的内容都打印到屏幕上。做完这些工作向各个登入用户发送信息。图用户登入后聊天图voidCTcpseverDlg::Onlisten(){CStringipstr,portstrintportGetDlgItemText(IDCEDIT,ipstr)severname=ipstrGetDlgItemText(IDCEDIT,portstr)portstrTrimLeft()portstrTrimRight()port=atoi(portstr)if(port>port<){SetDlgItemText(IDClisten,"正在监听……")if(cslistenCreate(port)){cslistenListen()cslistensetp(this,csnum)cslistenListen()CWnd*cw=GetDlgItem(IDCEDIT)cw>EnableWindow(false)cw=GetDlgItem(IDCEDIT)cw>EnableWindow(false)cw=GetDlgItem(IDClisten)cw>EnableWindow(false)cw=GetDlgItem(IDCEDIT)cw>SetWindowText("本服务器名称为:"severname"rn正在后台等待用户连接,监听端口:"portstr"……")}else{MessageBox("绑定监听端口失败,请确认该端口没有被其它程序占用")cslistenClose()}CStringstrServ,strPortCWnd*wndwnd=GetDlgItem(IDCEDIT)wnd>GetWindowText(strServ)wnd=GetDlgItem(IDCEDIT)wnd>GetWindowText(strPort)wnd=GetDlgItem(IDCSERVINFORM)wnd>SetWindowText("n****************服务器名称:n"strServ"nn端口号:"strPort"nn协议类型:TCPn传输控制协议n****************")}else{MessageBox("端口输入有误,请重新输入")}}前面一部分代码捕捉了端口号但是端口号是以字符串的形式处理的而不是数字。函数TrimLeft和TrimRight分别意为裁掉该端口字符串的左边空格和右边空格。这样防止了用户某些习惯性输入错误。当正确输入端口号后创建了一个监听套接字并对端口进行监听。然后通过EnableWindow()把某些窗体设置为不可点击。最后再把信息反馈到屏幕上打印出来。右边有个图片设置可以点击图片更改到下一幅。再下面就是服务器信息。打印出了服务器的监听端口号昵称等等这些由程序动态获取。最后是个公告信息可以直接点击进行编辑。贴出部分实现代码:voidCTcpseverDlg::OnPic(){staticintindexindexindex=indexCBitmapbitmapintbit={IDBBITMAP,IDBBITMAP,IDBBITMAP,IDBBITMAP,IDBBITMAP}bitmapLoadBitmap(bitindex)msetPicModifyStyle(,SSBITMAP)msetPicSetBitmap((HBITMAP)bitmapDetach())}这是点击改变图片的代码在VC中ID号其实就是一些整数的标记把ID存入一个整型数组中实现没点击图片一次自动更换ID。这样可以实现动态改变图片。voidCTcpseverDlg::OnMarkst(){CWnd*wndCStringstrwnd=GetDlgItem(IDCMARKST)wnd>GetWindowText(str)wnd>ShowWindow(SWHIDE)wnd=GetDlgItem(IDCMARK)wnd>ShowWindow(SWSHOW)wnd>SetWindowText(str)}这是公布框的设计其实在同一区域中摆放了两个控件一个静态文本一个编辑框。在设计的过程中对话框的初始化函数中对两个控件做了设置。将静态文本显示编编辑框隐藏并且设置静态文本中的内容和编辑框一样。这样当启动服务端后显示出来的就是静态文本了这样比较美观。上面函数意思为当点击静态文本时先获取文本中的内容然后将其隐藏。再将编辑框显示出来设置编辑框中的内容为开始获取的静态文本中内容。这样就可以和设置QQ心情一样的设置文本内容了。这样实现起来比较简单方便无需弹出一个对话框设置。设置好文本后点击编辑框以外的任何地方都可以把内容做更新。然后隐藏编辑框显示静态文本。这样就要建立一个系统响应函数对MouseClick消息做一个捕获。代码见下:voidCTcpseverDlg::OnLButtonDown(UINTnFlags,CPointpoint){CWnd*wndCStringstrwnd=GetDlgItem(IDCMARK)wnd>GetWindowText(str)wnd>ShowWindow(SWHIDE)wnd=GetDlgItem(IDCMARKST)wnd>ShowWindow(SWSHOW)wnd>SetWindowText(str)CDialog::OnLButtonDown(nFlags,point)}该函数当点击对话框时会被系统自动调用函数将编辑框中上的内容设置到了静态文本中然后显示静态文本隐藏了编辑框。有一个问题就是在初始化函数中为什么要将静态文本的内容复制到编辑框中呢?这个必须要复制的不然在启动程序后任何时候点击对话框都会将静态文本内容置空。这个可以去理解一下。下图显示了点击公告栏和图片后的情况:图修改资料效果图在服务器中有个”<<”收缩符号当点击它以及它所在位置的垂直方向时可以把右边区域收缩起来。这样可以去掉不是很关心的内容。当点击后侧边栏又显示出”>>”符号。再次点击又会还原出来。图精简视图voidCTcpseverDlg::OnShow(){TODO:AddyourcontrolnotificationhandlercodehereCStringstrstaticCRectrectLargestaticCRectrectSmallCRectrectSeparateif(rectLargeIsRect()){GetWindowRect(rectLarge)GetDlgItem(IDCSEPARATE)>GetWindowRect(rectSeparate)rectSmalltop=rectLargetoprectSmallleft=rectLargeleftrectSmallbottom=rectSeparatebottomrectSmallright=rectSeparateright}if(GetDlgItemText(IDCSHOW,str),str=="nnnnnnnnnnnnnnn<<"){str="nnnnnnnnnnnnnnn>>"SetDlgItemText(IDCSHOW,str)SetWindowPos(,,,rectSmallWidth(),rectSmallHeight(),SWPNOMOVE|SWPNOZORDER)}else{str="nnnnnnnnnnnnnnn<<"SetDlgItemText(IDCSHOW,str)SetWindowPos(,,,rectLargeWidth(),rectLargeHeight(),SWPNOMOVE|SWPNOZORDER)}}实现该过程的核心思想是选择两个矩形区域并记录下他们的位置点坐标。GetWindowRect(rectLarge)这个函数就是记录下整个对话框的大小尺寸等信息。并把记录下的数据填入rectLarge中。然后设置要裁剪的区域同样的方式用GetDlgItem(IDCSEPARATE)>GetWindowRect(rectSeparate)记录矩形区域信息。这样当点击按钮时自动识别要做怎样的处理。更具Z规则设置某个视图在最上方这样就成功的隐藏了要截取的区域。客户端的编程和服务端基本差不多这里不做详细论述。值得注意的一点是当服务器退出后客户端断开连接要提示给用户。见下图:图提示断开连接在CSocket中前面也提到过当某个套接字获取到消息与其连接的套接字断开连接后。系统会自动获取该消息并有应用程序框架自动调用函数OnClose。在OnClose中可以设置一些代码给出相关操作。服务端中要派生出自己的csocket类基类可以选择CAsyncSocket也可以是CSocket。在CAsyncSocket中定义了很多被框架自动调用的虚函数编程时要重写这些函数。classcsocket:publicCSocket{public:voidOnReceive(inti){dlg>onrev(mynum)}voidOnAccept(inti){dlg>onac()}voidOnClose(inti){dlg>oncl()}voidsetp(CTcpseverDlg*severdlg,intnum){mynum=numdlg=severdlg}private:CTcpseverDlg*dlgintmynum}代码中OnReceive是当有消息到来时框架调用该函数。OnAccept为当连接成功后调用。OnClose为当失去连接后系统自动调用。在这些函数中分别做了自己的事情。写入自己的函数。Onrev函数前面已经介绍过这里介绍其他的几个关键函数。voidCTcpseverDlg::onac(){cslistenAccept(csrevcsnum)csrevcsnumsetp(this,csnum)}Onac函数作用是接受连接并且让连接的套接字计数加一。voidCTcpseverDlg::oncl(){for(inti=i<=csnumi)if(!csrevi)csreviClose()}当服务器退出后要释放服务器创建的套接字资源这个函数也就是起到了这个作用。voidCTcpseverDlg::OnMouseMove(UINTnFlags,CPointpoint){UpdateData()if(mrecvCtr==""){GetDlgItem(IDCCLEAN)>EnableWindow(false)}else{GetDlgItem(IDCCLEAN)>EnableWindow(true)}CDialog::OnMouseMove(nFlags,point)}该函数是设置“清空”按钮的状态的当鼠标在对话框中移动时检测状态。当屏幕内容不为空时。清空按钮可以点解否者则为灰色按钮。结论在刚进行该应用软件开发的时可谓难以下手对VC编程有所了解但是网络一块很少涉及经过学习和请教知道了套接字可以实现网络数据传输。起初选用的是SOCKET,该方法为网络编程的最基础实现。虽然MFC封装了很多有关套接字的API函数但实现起来也不简单对底层数据分析和实现要求较高。最初用SOCKET实现的时候设置连接成功但是整个服务器等待监听以后便处于一种死锁状态。虽然客户端成功接入但是服务端始终不能进行任何操作甚至会出现无响应情况。对于这问题可谓百思不得其解在一次不经意的学习中发现了阻塞这种说法虽然之前也知道SOCKET是堵塞编程但对阻塞一词还是不明其意。在后来的学习中终于了解到多线程编程的重要性之前的整个程序只有一个主线程线程一直会停留在监听状态程序肯定不能运行其他功能!发现问题后又开始学习多线程编程准备分出一条线程处理监听事件其它的线程处理其它事件。当成功开辟线程后在声明的线程函数中写入了监听代码监听顺利完成然而问题接着又来了。线程函数可声明为全局函数或者是类的静态函数为了维护代码的封装性开发中选择了后者。对于线程函数中收到的消息怎么传回给对话框呢?最初试图通过定义一个全局变量再用API函数SetDlgItem()处理但是编译出现了问题指出申明的全局变量没有定义。线程函数定义为全局函数(也可以使某个类的静态函数)为什么线程里的数据不能直接传送呢?最后只得采用PostMessage()的方法将消息回传这次成功的完成了消息传递。接着问题又出现了虽然成功的接受和发送了消息但是消息最后会出现乱码。对于出现乱码的问题一般是数组越界访问才会发生在设计的过程中最好是对数组进行安全性检测。可是这次的乱码出现不同寻常最后也没一个很好的解释只有另寻他径完成设计。需要指出的一点不提倡使用全局函数和变量是有原因的。全局函数和变量虽然对很多棘手的问题都能方便实现但是对程序的封装性和可移植性是个很大的挑战。C的优点便在于多态的实现和程序的封装程序员会尽量去提高整个程序的低耦合度让开发的程序便于移植。在多文件程序中全局变量可能在多个地方被修改所以维护起来麻烦在查错时也不好发现。而且全局变量可能会出现重复定义问题使编译出现错误。之后学习了CSocket类及其实现过程发现这是一种非阻塞的网络编程实现很简单可以不用开辟线程处理监听等事件。鉴于CSocket确实有很多可取之处而发送消息出现乱码问题始终没有解决所以最后采用了CSocket完成了任务。在CSocket中当应用程序框架收到某些特殊事件的消息时会自动调用某些函数在这些特殊的函数中可以写入自己的代码来完成某些事件。CSocket是在CAsyncSocket基础上扩展的类CAsyncSocket封装了很多函数其中的OnAccept、OnSend、OnReceive、OnClose、OnConnect函数被应用程序框架自动调用。这些函数分别在连接、发送消息、接受到消息及断开连接时被调用所以可以很方便的在这些函数里面添加自己的代码来完成通讯。但需要注意的是这些都是虚函数在使用前必须构建新的继承于CAsyncSocket或CSocket的类再在类中重新定义这些函数完成调用。如果不这样做应用程序框架也会调用上述函数但不会实现任何内容。服务器监听时要设置监听端口创建监听套接字这样客户端才可以成功监听。客户端用函数Connect()请求连接当连接成功后框架自动调用函数OnAceept()。然后连入服务器的客户端就可以进行聊天了。在聊天过程中当消息到来时框架会自动调用函数OnReceive可以在这个函数内部写入函数Receive()接收消息。当某个用户退出聊天室后框架会自动调用函数OnClose()这样就可以实时的获取用户的活动情况正确的显示在线状态并发送用户退出信息。服务器将所有客户端连接在一个网络中所有客户端发送的信息都是发送到服务器通过消息过滤后服务器再将其发送给各个客户端。所以服务器的工作量非常大。如果是进行大规模的图片、语音、视频传输时特别是在用户很多的情况下服务器承受的压力也是很大的。多服务器的连入很有必要可以解决信息堵塞问题。在开发的过程中原想进行更多研究比如图片发送、抖动窗口、语音视频发送、以及文件传送等等。但是发现自己掌握的知识有限并且时间短暂所以只实现了文字聊天功能。在成功完成文字聊天后也尝试过发送语音信息在调用API函数检测硬件信息时便出现了问题。对于未知的错误信息总是难以下手在网上也找到了很多有关这些错误的解决方法不过最终没有成功完成语音的发送。当基本功能实现后便开始实现界面设计看了孙鑫的视频教学对基本界面开发也有所了解。对腾讯QQ软件的写入状态比较感兴趣。当点击状态栏时那块区域会变成可编辑的状态并且那些以前已经存在的文字会被全部选中。当时很疑惑为什么点中了就可以变成编辑框写入文字反复思考斟酌最后还是知道该如何实现。可以在某片区域摆放两个控件静态文本和编辑框。静态文本用于显示文字编辑框用于编辑输入文字。当点击那片区域后隐藏静态文本显示编辑框。当移动鼠标点击那块区域以外的任何一个区域时便显示静态文本影藏编辑框。当然其中还涉及了信息的传输等问题。在整个软件开发的过程中感觉自己做的不是很好尤其是时间上的安排不是很合理。在编写代码前对相应知识更是知道甚少。但是通过不断的努力学习终于有所收获成功解决众多问题。这也证实了只有有了压

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/40

基于VC的局域网聊天室

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利