资源描述
成都理工大学工程技术学院毕业论文基于socket的网络聊天室作者姓名:陈 聪 专业名称:计算机科学与技术指导教师:柳 军 讲师基于socket的网络聊天室摘要八十年代初,美国政府的高级研究工程机构(ARPA)给加利福尼亚大学Berkeley分校提供了资金,让他们在UNIX操作系统下实现TCP/IP协议。在这个项目中,研究人员为TCP/IP网络通信开发了一个API(应用程序接口)。这个API称为Socket接口(套接字)今天,SOCKET接口是TCP/IP网络最为通用的API,也是在INTERNET上进行应用开发最为通用的API.。WINSOCK 是在Windows进行网络通信编程的API接口,也是Windows网络编程的事实标准。在网络编程中最常用的方案便是客户机/服务器模型(C/S)。本文提出了在客户机/服务器模型下用WINSOCK实现的聊天室软件的方案。随着网络技术的发展及人们生活的需求,网络聊天已越来越受到人们的亲睐 。本课题是开发一个基于TCP的局域网聊天室系统,采用软件工程的方法,综合运用数据库技术、程序设计技术、网络技术。研究的主要内容是如何利用TCP套接字编写网络聊天程序,主要完成了客户端的号码注册,发送信息与显示在线用户及服务器端的广播信息,管理用户数据库与在线用户显示等工作.通过聊天工具的使用,让分布在不同地点、使用不同机器的一组用户能够及时进行信息交流.达到信息共享的目的.从而提高工作或者生活效率。考虑到对用户的管理及安全性问题,增加了管理数据库功能。适用于局域网使用的网络聊天工具,其操作简单,灵活性好,运行也比较稳定。关键字 :C/S 套接字 TCPAbstractThe early 80s, the U.S. governments Advanced Research Project agency (ARPA) to the University of California, Berkeley provided funding to enable them to achieve in the UNIX operating system, TCP / IP protocol. In this project, researchers for the TCP / IP Network Communication Development an API (application program interface). This API is called Socket Interface (socket). Today, SOCKET interface is a TCP / IP network of the most common API, is the INTERNET application development on the most common API.WINSOCK network communication in the Windows API programming interface, is the de facto standard Windows network programming. In network programming is the most commonly used program client / server model. In this paper, the client / server model implemented using WINSOCK chat room software program.With the development of networking technology and the living demand of people,chating on network is more and more acceptable by people .This topic is going to talk about that to develop the local area internet chatroom system which based on UDP , It adopts the method of software engineer ,and uses the technology of database , process design and network synthetichy .The prinary content of researching is how to use the UDP sleeve to joint the procedure of compiling the network chat, it is main to finish the task of the numbers application of clients, transmiting the message,displaying the online users and the servers broadcast message, and managing users database and the displaying of online users.Through the using of chating tool,it can make a group of users who distribute in different place ,and use different machine to communicate with senting messages timely,then achieved the goal of information sharing, and inprove the efficiency of work or living .To consider the managing and secure problem to users , it increases the function of managing database,.It adapts to use the network chating tool in local internet ,its operation is simple , the flexibility is good and movement is also guite stableKeywords: C/S, SOCKET, TCP- II -基于socket的网络聊天室目录摘要IAbstractII目录III前言11 开发环境介绍21.1 Visual C+可视化集成开发环境简介21.2 VC+ MFC编程21.2.1 MFC类库概念和组成31.2.2 MFC的优点31.3 Winsock网络编程41.3.1 Socket41.3.2开发Windows Sockets网络通信程序的软、硬件环境51.3.3 CSocket类编程模型61.3.4 用VC6.0进行Windows Sockets程序开发的技术要点62 Microsoft Access概述82.1 Microsoft Access的发展82.2 Microsoft Access的主要用途82.3本系统的数据库设计93 ODBC原理及其MFC编程103.1 ODBC概述103.2 ODBC接口的工作原理113.3 ODBC数据源的创建及连接113.4 MFC 的ODBC编程124 需求分析144.1 开发平台144.2 网络聊天室的流程及模型图144.2.1 流程图144.2.2 系统数据模型(E-R图)154.3 网络聊天室的主要实现154.3.1 登陆以及身份确认(密码验证)功能的实现:154.3.2 客服端聊天功能实现204.3.3 服务器端功能实现225 系统实现245.1对所有的用户发送谁进入了聊天室及头像的加载245.2 服务器自定义消息处理函数25总结31致谢32参考文献33-33-前言随着网络技术的普及,计算机应用正从传统的单用户工作模式向多用户信息交流共享工作的方向发展。在工作过程中,多个用户交流信息即需要使多台机器能够联网并能交流数据,这样就必须要有个大家都认同的方式来实现这个目的,这时就需选择已经开发的TCP协议,在这个协议中,定义一个套接字(Socket)来帮助用户完成通信,套接字(Socket)最初是由加利福尼亚大学Berkeley分校为UNIX操作系统开发的网络通信接口,随着UNIX操作系统的广泛使用,套接字成为当前最流行的网络通信应用程序接口之一。九十年代初,由Sun Microsystems,JSB Corporation,FTP software,Microdyne和Microsoft等几家公司共同制定了一套标准,即Windows Sockets规范。本设计是建立在套接字(Socket)的基础上的。局域网聊天室系统设计可以划分为三个子系统:服务器管理员登陆,开启服务器及广播信息子系统、客户端用户申请账号子系统、客户端用户聊天子系统。客户端用户聊天子系统是客户端程序的重要组成部分,要能正常的发送信息功能。能申请账号、能显示在线用户、能给任意在线用户发送信息等,服务器端管理员能够登陆而使服务器具有安全性、服务器端能够广播信息而通知大家重要信息、服务器能够管理用户。本论文主要讲叙了基于VC+的Client/Server模式的开发。不足之处本系统只能用于小型的网络中,比方说在一个办公室、一个公司、一个居民小区等地方使用。1 开发环境介绍1.1 Visual C+可视化集成开发环境简介Visual C+是一个功能强大的可视化软件开发工具。自1993年Microsoft公司推出Visual C+1.0后,随着其新版本的不断问世,Visual C+已成为专业程序员进行软件开发的首选工具。 虽然微软公司推出了Visual C+.NET(Visual C+7.0),但它的应用的很大的局限性,只适用于Windows 2000,Windows XP和Windows NT4.0。所以实际中,更多的是以Visual C+6.0为平台。Visual C+6.0不仅是一个C+编译器,而且是一个基于Windows操作系统的可视化集成开发环境(integrated development environment,IDE)。Visual C+6.0由许多组件组成,包括编辑器、调试器以及程序向导AppWizard、类向导Class Wizard等开发工具。 这些组件通过一个名为Developer Studio的组件集成为和谐的开发环境。现在最新版本是vc 2010 ,对c+标准支持的最好1.2 VC+ MFC编程在微软基础类库(MFC:Microsoft Foundation Class)是微软为Windows程序员提供的一个面向对象的Windows编程接口,它大大简化了Windows编程工作。使用MFC类库的好处是:首先,MFC提供了一个标准化的结构,这样开发人员不必从头设计创建和管理一个标准Windows应用程序所需的程序,而是“站在巨人肩膀上”,从一个比较高的起点编程,故节省了大量的时间;其次,它提供了大量的代码,指导用户编程时实现某些技术和功能。MFC库充分利用了Microsoft开发人员多年开发Windows程序的经验,并可以将这些经验融入到你自己开发的应用程序中去。对用户来说,用MFC开发的最终应用程序具有标准的、熟悉的Windows界面,这样的应用程序易学易用;另外,新的应用程序还能立即支持所有标准Windows特性,而且是用普通的、明确定义的形式。事实上,也就是在Windows应用程序界面基础上定义了一种新的标准MFC标准。为了更好的理解MFC,我们有必要了解一下MFC的历史。1.2.1 MFC类库概念和组成类库是一个可以在应用中使用的相互关联的C+类的集合。类库有些随编译器提供,如Borland C+ Turbo Vision等;有的是由其他软件公司销售,如用于数据库开发的CodeBase;有的则是由用户自己开发的。比如图象处理类库完成图象显示、格式转换、量化等;串行通信类库用于支持串行口输入输出。有些情况下用户可以直接利用类库中包含的类定义应用程序所需的变量,有时则需要从类库所提供的类中派生出新的类,这依赖于类库的设计和具体的应用程序。Microsoft提供了一个基础类库MFC,其中包含用来开发C+和C+ Windows应用程序的一组类。基础类库的核心是以C+形式封装了大部分的Windows API。类库表示窗口、对话框、设备上下文、公共GDI对象如画笔、调色板、控制框和其他标准的Windows部件。这些类提供了一个面向Windows中结构的简单的C+成员函数的接口。MFC可分为两个主要部分:(1)基础类(2)宏和全程函数。1.2.2 MFC的优点Microsoft MFC具有以下不同于其它类库的优势:1.完全支持Windows所有的函数、控件、消息、GDI基本图形函数,菜单及对话框。类的设计以及同API函数的结合相当合理。2.使用与传统的Windows API同样的命名规则,即匈牙利命名法。3.进行消息处理时,不使用易产生错误的switch/case语句,所有消息映射到类的成员函数,这种直接消息到方法的映射对所有的消息都适用。它通过宏来实现消息到成员函数的映射,而且这些函数不必是虚拟的成员函数,这样不需要为消息映射函数生成一个很大的虚拟函数表(V表),节省内存。4.通过发送有关对象信息到文件的能力提供更好的判定支持,也可确认成员变量。5.支持异常错误的处理,减少了程序出错的机会6.运行时确定数据对象的类型。这允许实例化时动态操作各域7.有较少的代码和较快的速度。MFC库只增加了少于40k的目标代码,效率只比传统的C Windows程序低5%。8.可以利用与MFC紧密结合的AppWizard和ClassWizard等工具快速开发出功能强大的应用程序。9.另外,在使用MFC时还允许混合使用传统的函数调用。1.3 Winsock网络编程Windows Sockets 是从 Berkeley Sockets 扩展而来的,其在继承 Berkeley Sockets 的基础上,又进行了新的扩充。这些扩充主要是提供了一些异步函数,并增加了符合WINDOWS消息驱动特性的网络事件异步选择机制。Windows Sockets由两部分组成:开发组件和运行组件。开发组件:Windows Sockets 实现文档、应用程序接口(API)引入库和一些头文件。运行组件:Windows Sockets 应用程序接口的动态链接库(WINSOCK.DLL)。1.3.1 Socket套接字(Socket)最初是由加利福尼亚大学Berkeley分校为UNIX操作系统开发的网络通信接口,随着UNIX操作系统的广泛使用,套接字成为当前最流行的网络通信应用程序接口之一。90年代初,由Sun Microsystems,JSB Corporation,FTP software,Microdyne和Microsoft等几家公司共同制定了一套标准,即Windows Sockets规范。 Windows Sockets API是Microsoft Windows的网络程序设计接口,它在继承了Berkeley Sockets主要特征的基础上,又对它进行了重要扩充。这些扩充主要是提供了一些异步函数,并增加了符合Windows消息驱动特性的网络事件异步选择机制 。这些扩充有利于应用程序开发者编制符合Windows编程模式的软件,它使在Windows下开发高性能的网络通信程序成为可能。 Socket实际上是指一个通信端点,借助于它,用户所开发的Socket应用程序,可以通过网络与其它Socket应用程序进行通信。 近年来,随着计算机网络与Windows 95的流行,许多用户所开发的应用程序需要实现网络间的数据通信。1.3.2开发Windows Sockets网络通信程序的软、硬件环境所采用的操作系统软件可以是Windows 95,2000,XP,也可以是Windows NT,因为它们都支持Windows Sockets API,在以下的介绍中,我们将以在Windows XP环境下的开发为例。 所采用的编程语言一般可选目前较流行使用的可视化和采用面向对象技术的Microsoft Visual C+ 6.0。Visual C+ 6.0可在Windows XP或Windows NT环境下运行,其开发系统增加了全面集成的基于Windows 的开发工具以及一个基于传统C/C+开发过程的“可视化”用户界面驱动模型。Visual C+ 6.0中的Microsoft基类(MFC,即Microsoft Foundation Class)库是一系列C+类,其中封装着为Microsoft Windows操作系统系列编写应用程序的各种功能 。在有关套接字方面,Visual C+ 6.0对原来的Windows Sockets库函数进行了一系列封装,继而产生了CSocket 、CSocketFile等类,它们封装着有关Socket的各种功能。 所采用的网络通信协议一般是TCP / IP。Windows XP和Windows NT都带有该协议。但是,所开发的网络通信应用程序并不能直接与TCP / IP核心打交道,而是与网络应用编程界面Windows Sockets API打交道。Windows Sockets API则可直接与TCP/IP核心进行沟通。TCP / IP核心协议连同网络物理介质(如网卡)一起,都是提供网络应用程序间相互通信的设施。计算机应满足Windows 95运行的配置要求。如果有条件,最好采用Pentium或其以上档次的微机,将内存配置到16MB,并采用1GB左右的硬盘。1.3.3 CSocket类编程模型使用CSocket对象涉及CArchive和CSocketFile 类对象。以下介绍的针对字节流型套接字的操作步骤中,只有第三步对于客户方和服务方操作是不同的,其他步骤都相同。 1.构造一个CSocket对象。 2.使用这个对象的Create()成员函数产生一个socket对象。在客户方程序中,除非需要数据报套接字,Create()函数一般情况下应该使用默认参数。而对于服务方程序,必须在调用Create时指定一个端口。需要注意的是,Carchive类对象不能与数据报(UDP)套接字一起工作,因此对于数据报套接字,CAsyncSocket和CSocket 的使用方法是一样的。 3.如果是客户方套接字,则调用CAsyncSocket Connect()函数与服务方套接字连接;如果是服务方套接字,则调用CAsyncSocketListen()开始监听来自客户方的连接请求,收到连接请求后,调用CAsyncSocketAccept()函数接受请求,建立连接。请注意Accept()成员函数需要一个新的并且为空的CSocket对象作为它的参数,解释同上。 4.产生一个CSocketFile对象,并把它与CSocket 对象关联起来。5.为接收和发送数据各产生一个CArchive 对象,把它们与CSocketFile对象关联起来。切记CArchive是不能和数据报套接字一起工作的。 6.使用CArchive对象的Read()、Write()等函数在客户与服务方传送数据。7.通讯完毕后,销毁CArchive、CSocketFile和CSocket对象。1.3.4 用VC6.0进行Windows Sockets程序开发的技术要点1.同常规编程一样,无论服务器方还是客户方应用程序都要进行所谓的初始化处理,这部分工作仍可采用消息驱动机制来先期完成。 2.一般情况下,网络通信程序是某应用程序中的一模块。在单独调试网络通信程序时,要尽量与采用该通信模块的其它应用程序开发者约定好,统一采用一种界面形式,即单文档界面SDI、多文档界面MDI和基于对话框界面中的一种(这在使用AppWizard形成项目Project文件时有提示),尽管这并非必须,但可使通信模块在移植到所需的应用程序时省时省力,因为Visual C+ 6.0这种可视化语言在给我们提供方便的同时,也给我们带来某些不便,譬如所形成的项目文件中的许多相关文件与所采用的界面形式密切联系,许多消息驱动功能,随所采用的界面形式不同而各异。 当然,也可将通信模块函数化,并形成一个动态连接库文件(DLL文件),供主程序调用。 3.以通信程序作为其中一个模块的应用程序往往不是在等待数据发送或接收完之后再做其它工作,因而在主程序中要采用多线程(Multithreaded)技术。即将数据的发或收,放在一个具有一定优先级(一般宜取较高优先级)的辅助线程中,在数据发或收期间,主程序仍可进行其它工作,譬如利用上一个周期收到的数据绘制曲线 。Visual C+ 6.0中的MFC提供了许多有关启动线程、管理线程、同步化线程、终止线程等功能函数。 4.在许多情况下,要求通信模块应实时地收、发数据。譬如调用之的主程序以0.5秒为一周期,在这段时间内 ,要进行如下工作:接收数据,利用收到的数据进行运算,将运算结果发送到其它计算机节点,周而复始。我们在充分利用Windows Sockets的基于消息的网络事件异步选择机制,用消息来驱动数据的发送和接收的基础上,结合使用其他措施,如将数据的收和发放在高优先级线程,在软件设计上,安排好时序,尽量避免在同一时间内,双方都在向对方发送大量数据的情况发生,保证网络要有足够的带宽等,成功地实现了数据传输的实时性。2 Microsoft Access概述Microsoft Office Access是由微软发布的关联式数据库管理系统。它结合了 Microsoft Jet Database Engine 和 图形用户界面两项特点,是 Microsoft Office 的系统程式之一。2.1 Microsoft Access的发展进入可提供的编程语言,当时在另一个内产品Microsoft Office家具,微软公司应用的Visual Basic。两个数据库进入讯息库COM组成部分被提供:这笔遗产数据存取物体(DAO),用进入和新只可提供ActiveX数据对象(忙乱)。MicrosoftAccess容易被应用于小的工程但是规模无效对大的工程如果应用被不好设计。全部数据库质问,形式和报告被储存在数据库里,并且与相关的模型的理想协调,没有与他们做一个身体上组织的阶层的可能性。一种设计技术是把进入应用在数据和计划之间进行分发。一数据库应该只包含桌子和关系,当另一个将有全部计划时,形式,报告和质问和对第一个数据库桌子的连接。令人遗憾,当连结时,进入允许没有有关的道路,因此那些发展环境作为这种生产环境有相同的道路应该(虽然你写你们自己的能动态连接程序常规在里VBA那搜出能一定背面结束档案以透过这个目录树搜寻,如果它发现这条电流通路它不能)。这种技术也允许开发者在不同的档案中分申请,因此一些架构是可能的。2.2 Microsoft Access的主要用途Microsoft Access在很多地方得到广泛使用,例如小型企业,大公司的部门,和喜爱编程的开发人员专门利用它来制作处理数据的桌面系统。它也常被用来开发简单的WEB应用程序这些应用程序都利用ASP技术在Internet Information Services运行比较复杂的WEB应用程序则使用PHP/MySQL或者ASP/Microsoft SQL Server它的使用方便程度和强大的设计工具为初级程序员提供许多功能。不过,这种便于使用可能使人误解。这类开发者都是没有在应用或者数据设计方面训练的办公室从业人员。因此许多人以为这样的开发者能够创造可用的系统,但也有很多人认为工具本身的局限性产生了这样的误导。一些专业的应用程序开发人员使用 Access 用作快速应用开发,特别是给街道上的推销员制作一个初型或独立应用程序的工具。可是如果是透个网络存取数据的话,Access 的可扩放性并不高因此当程序被较多使用者使用时,他们的选择多会是倾向于一些客户端-服务器为本的方案,例如 Oracle、DB2、Microsoft SQL Server、Windows SharePoint Services、PostgreSQL、MySQL、Alpha Five、MaxDB,或者Filemaker。无论如何,不少 Access 的功能(表单,报告,序列和VB代码)可以用作其他数据库的后期应用,包括 JET(档案为主的数据库引擎,Access 缺省使用)、Microsoft SQL Server、Oracle和任何其他跟ODBC兼容的产品。这种方法允许开发者把一个成熟的应用的数据移动到一台更大功率的服务器而没有已经在适当的位置牺牲发展。很多开发者谁使用Microsoft Access使用Leszynski命名约定,虽然这不普遍;它是一次编程大会,并非一个DBMS实施的规章。2.3本系统的数据库设计图2.1用户信息表user这张表很简单,主要用于注册账号和验证账号登陆等功能,存着用户的用户名,密码和头像。3 ODBC原理及其MFC编程3.1 ODBC概述ODBC(Open Database Connectivity,开放数据库互连)是微软公司开放服务结构(WOSA,Windows Open Services Architecture)中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准API(应用程序编程接口)。这些API利用SQL来完成其大部分任务。ODBC本身也提供了对SQL语言的支持,用户可以直接将SQL语句送给ODBC。一个基于ODBC的应用程序对数据库的操作不依赖任何DBMS,不直接与DBMS打交道,所有的数据库操作由对应的DBMS的ODBC驱动程序完成。也就是说,不论是FoxPro、Access还是Oracle数据库,均可用ODBC API进行访问。由此可见,ODBC的最大优点是能以统一的方式处理所有的数据库。一个完整的ODBC由下列几个部件组成:1.应用程序(Application)。2.ODBC管理器(Administrator)。该程序位于Windows 95控制面板(Control Panel)的32位ODBC内,其主要任务是管理安装的ODBC驱动程序和管理数据源。3.驱动程序管理器(Driver Manager)。驱动程序管理器包含在ODBC32.DLL中,对用户是透明的。其任务是管理ODBC驱动程序,是ODBC中最重要的部件。4.ODBC API。5.ODBC 驱动程序。是一些DLL,提供了ODBC和数据库之间的接口。6.数据源。数据源包含了数据库位置和数据库类型等信息,实际上是一种数据连接的抽象。应用程序要访问一个数据库,首先必须用ODBC管理器注册一个数据源,管理器根据数据源提供的数据库位置、数据库类型及ODBC驱动程序等信息,建立起ODBC与具体数据库的联系。这样,只要应用程序将数据源名提供给ODBC,ODBC就能建立起与相应数据库的连接。在ODBC中,ODBC API不能直接访问数据库,必须通过驱动程序管理器与数据库交换信息。驱动程序管理器负责将应用程序对ODBC API的调用传递给正确的驱动程序,而驱动程序在执行完相应的操作后,将结果通过驱动程序管理器返回给应用程序。在访问ODBC数据源时需要ODBC驱动程序的支持。3.2 ODBC接口的工作原理 应用程序要访问一个数据库,首先必须用ODBC管理器注册一个数据源,管理器根据数据源提供的数据库位置、数据库类型及ODBC驱动程序等信息,建立起ODBC与具体数据库的联系。这样,只要应用程序将数据源名提供给ODBC,ODBC就能建立起与相应数据库的连接。3.3 ODBC数据源的创建及连接1.操可通过两种方法连接到 ODBC 数据源: (1)使用设计时工具直观操作。 (2)使用编程方式操作。 2.在服务器资源管理器中连接到 ODBC 数据源在服务器资源管理器中建立了与 ODBC 数据源的连接之后,只需轻松地将数据对象从服务器资源管理器拖到窗体或设计器上,即可创建 OdbcConnection、OdbcDataAdapter 和 OdbcCommand 对象。3.在服务器资源管理器中创建连接 在服务器资源管理器中,右击“数据连接”,然后单击“添加连接”。在“数据链接属性”对话框中,单击“提供程序”选项卡。 单击“用于 ODBC 驱动程序的 Microsoft OLE DB 提供程序”,然后单击“下一步”。 从列表中选择要访问的 ODBC 数据源,或者键入要访问的 ODBC 数据源的名称。 键入登录到数据源时要用于身份验证的“用户名称”。 键入登录到数据源时要用于身份验证的密码。 单击“确定”。 从应用程序连接到 ODBC 数据源。4.从应用程序创建到数据源的连接有两种方法,一是使用 Visual Studio .NET 设计器直观地完成,一是通过使用代码创建数据连接对象以编程方式完成。以直观方式连接到 ODBC 数据源Visual Studio 支持通过以下方式创建数据对象,即将项从服务器资源管理器或“工具箱”的“数据”选项卡中拖到窗体或设计器上。从服务器资源管理器创建连接 在服务器资源管理器中创建与 ODBC 数据源的“数据连接” 将连接拖到窗体或设计器上。OdbcConnection 对象出现在组件栏中。将 OdbcConnection 拖到窗体或设计器上。一个未配置的 OdbcConnection 对象出现在组件栏中。在“属性”窗口中,单击 ConnectionString 属性。在下拉列表中选择现有连接,或者单击“新建连接”打开“数据链接属性”对话框并配置新连接。 5.以编程方式连接到 ODBC 数据源您可以直接在代码中创建 OdbcConnection 对象。3.4 MFC 的ODBC编程通过VC+中MFC ODBC对数据库访问技术简单介绍,工程人员在软件开发过程中,可以根据实际情况选择相关技术,减少了软件开发的工作量,缩短开发周期,提高了效率和软件的可靠性。MFC的ODBC类对较复杂的ODBC API进行了封装,提供了简化的调用接口,从而大大方便了数据库应用程序的开发。程序员不必了解ODBC API和SQL的具体细节,利用ODBC类即可完成对数据库的大部分操作。MFC的ODBC类主要包括:CDatabase类:主要功能是建立与数据源的连接。CRecordset类:该类代表从数据源选择的一组记录(记录集),程序可以选择数据源中的某个表作为一个记录集,也可以通过对表的查询得到记录集,还可以合并同一数据源中多个表的列到一个记录集中通过该类可对记录集中的记录进行滚动、修改、增加和删除等操作。CRecordView类:提供了一个表单视图与某个记录集直接相连,利用对话框数据交换机制(DDX)在记录集与表单视图的控件之间传输数据。该类支持对记录的浏览和更新,在撤销时会自动关闭与之相联系的记录集。CFieldExchange类:支持记录字段数据交换(DFX),即记录集字段数据成员与相应的数据库的表的字段之间的数据交换。该类的功能与CDataExchange类的对话框数据交换功能类似。CDBException类:代表ODBC类产生的异常。概括地讲,CDatabase针对某个数据库,它负责连接数据源;CRecordset针对数据源中的记录集,它负责对记录的操作;CRecordView负责界面,而CFieldExchange负责CRecordset与数据源的数据交换4 需求分析4.1 开发平台应用本程序是在windows XP的系统下用Visual C+6.0进行开发的,用的是Microsoft Accesss的数据库。4.2 网络聊天室的流程及模型图4.2.1 流程图图4.1系统登录流程图4.2.2 系统数据模型(E-R图)账号头像 密码 用 户 port ip n 图4.2 系统数据模型图用户( 账号 ,密码,IP,PORT,头像)4.3 网络聊天室的主要实现4.3.1 登陆以及身份确认(密码验证)功能的实现:用户在登录界面输入用户ID和密码,系统进行用户身份验证,如果通过用户身份验证则转入相应的工作界面,如果没有通过用户身份验证则显示下列信息:用户名或者密码错误。用户可以重新输入正确的ID和密码。 输入用户名,密码 确认提交用户身份验证结果noYes 显示聊天页面显示错误信息图 4.3用户登录流程图用户登陆的界面:采用填文本框的方式填写用户名,密码,服务器IP,和端口,以及确定、退出、注册按钮。图4.4 用户登录界面图其中用户名,服务器IP, 端口号都用到了注册表存取配置信息技术。具体实现为:DWORD Size = 20;TCHAR Values20;CRegKey RegKey;if(RegKey.Open(HKEY_LOCAL_MACHINE,SoftwareChatChatRoom) = ERROR_SUCCESS)if(RegKey.QueryValue(Values,LoginName,&Size)=ERROR_SUCCESS)m_sUId = Values;Size = 20;if(RegKey.QueryValue(Values,Port,&Size)=ERROR_SUCCESS)m_Port = atoi(Values);Size = 20;if(RegKey.QueryValue(Values,SeverIP,&Size)=ERROR_SUCCESS)m_IP = Values;UpdateData(false);elseSetDlgItemText(IDC_EDIT2,2222); SetDlgItemText(IDC_IP,CPublic:GetLocalIp();意思是如果注册表中存储到有用户名,服务器IP,端口号等这些信息,那么就从注册表中把这些信息的值取出来赋给和登录界面的控件相对应的变量上,然后调用UpdateData(false);方法把变量的值更新到与变量相关联的控件上,如果注册表中没用这些信息,那么就把端口号控件框设为2222,然后把服务器的IP地址控件框通过调用CPublic:GetLocalIp() 进行设置。 CPublic为一个公共类,其中主要就是一个GetLocalIp()方法,这个方法的作用就是获取本机的IP,这是为了测试及演示的方便性考虑的。建CPubic这个公共类的主要目的是为了在各个页面更方面的调用GetLocalIp()方法。界面上有3个button按钮。1.退出为MFC的取消按钮,功能及为取消登录。2.注册功能:弹出注册界面注册界面中可以输入用户名,密码,可以选择头像。 注册的原理为套接字加消息机制把注册信息(用户名,密码,头像)传给服务器。当服务器返回RegisterOK$字符串时及表示登录成功。其中调用了InitSocketClient()函数 这个函数主要用做客服端socket的建立和连接服务器其中的winsocket编程之套接字原理如下:图4.5 套接字原理图注册成功后就可以登录了。3.登录把用户名,密码等信息用Socket传给服务器,返回posswordok字符串及登录成功。之后把用户信息存入注册表中。之后进入聊天界面。4.3.2 客服端聊天功能实现用户聊天界面,上面部分显示有用户的账号,服务器的IP ,和用户自己的IP地址。其中服务器IP的值是在ChatClient.h 头文件中定义了个CString SIP 。然后用(CChatClientApp*)AfxGetApp()-SIP;进行调用。我的IP的值依然是调用CPublic:GetLocalIp()函数得到的。下面就是消息区:左边为在线用户列表,其中每一项为用户的头像和用户名初始化列表为一个函数,如下:BOOL CChatClientDlg:InitListCtrl()/图像列表控制(CImageList)是相同大小图像的一个集合,每个集合中均以0为图像的索引序号基数,图像列表通常由大图标或位图构成,其中包含透明位图模式m_imageList.Create(32, 32, ILC_MASK|ILC_COLOR8, 0, 7);/Create 初始化图像列表并for(int i=0; iLoadIcon(IDI_ICON1+i);/添加一个或多个图象到图象列表中m_listUser.SetImageList(&m_imageList, LVSIL_SMALL);/指定一个图象列表到列表视图控件/CListCtrl类封装“列表视图控件”功能,显示每个包含图标(列表视图中)和标签的收集。除图标和标签外,每一项还能有显示在图标和标签的右边的列中的信息CRect rect;/CRect类与Windows RECT结构相似,并且还包括操作CRect对象和Windows RECT结构的成员函数/RECT结构定义了矩形的左上角坐标和右下角坐标m_listUser.GetClientRect(&rect);/该函数获取窗口客户区的坐标。m_listUser.InsertColumn(0, _T(用户列表), LVCFMT_CENTER, rect.right);/插入列表视图控件中的新列return TRUE;然后这个聊天室的核心就是用到了套接字非阻塞模式中的WSAAsyncSelect(异步选择)模型简述:通知套接口有请求事件发生. #include int PASCAL FAR WSAAsyncSelect ( SOCKET s, HWND hWnd,unsigned int wMsg, long lEvent ); s 标识一个需要事件通知的套接口的描述符.hWnd 标识一个在网络事件发生时需要接收消息的窗口句柄.wMsg 在网络事件发生时要接收的消息.lEvent 位屏蔽码,用于指明应用程序感兴趣的网络事件集合.注释:本函数用来请求Windows Sockets DLL为窗口句柄发一条消息无论它何时检测到由lEvent参数指明的网络事件.要发送的消息由wMsg参数标明.被通知的套接口由s标识.本函数自动将套接口设置为非阻塞模式.lEvent参数由下表中列出的值组成.值意义:FD_READ 欲接收读准备好的通知.FD_WRITE 欲接收写准备好的通知.FD_OOB 欲接收带边数据到达的通知.FD_ACCEPT 欲接收将要连接的通知.FD_CONNECT 欲接收已连接好的通知.FD_CLOSE 欲接收套接口关闭的通知. 启动一个WSAAsyncSelect()将使为同一个套接口启动的所有先前的WSAAsyncSelect()作废. 例如,要接收读写通知,应用程序必须同时用FD_READ和FD_WRITE调用WSAAsyncSelect(),如下:rc = WSAAsyncSelect(s, hWnd, wMsg, FD_READ|FD_WRITE);程序中为::WSAAsyncSelect(CChatClientApp*)AfxGetApp()m_socketClient,thisGetSafeHwnd(),WM_CLIENT,FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE);其中WM_CLIENT为自定义的消息然后为它定义了一个消息处理函数LRESULT CChatClientDlg:OnClient(WPARAM wParam,LPARAM lParam)其中主要判断lParam 为FD_CONNECT FD_READ FD_WRITE还是FD_CLOSE以及对相关情况进行处理其中FD_READ情况为主,包含了登录的情况,其他用户退出的情况以及正常发送消息的情况。右边为消息显示区域:有服务器发送的消息,其他用户发送的消息,以及自己发送的消息。最下边的区域为编写自己的消息,然后通过发送按钮发送出去4.3.3 服务器端功能实现服务器端的界面和客服端聊天界面基本一样,只是最上面的多了个启动服务器按钮 其中也用到了套接字非阻塞模式中的WSAAsyncSelect自定义了WM_SERVER消息及处理函数LRESULT CChatSeverDlg:OnServer(WPARAM wParam,LPARAM lParam)这个函数也是其处理核心。与客服端的处理函数类似。然后还建了一个CUserInformation类用于储存用户的一些资料。成员函数如下:SOCKET ISocket;int IIndex;CString IName;CString IPassword;int InItem;然后建立了一个CUserRecordSet类继承自CRecordset这个类主要与Access的user表进行对应。该CUserRecordSet将包含一组的数据成员对应与数据字段,如user表里面的文本列name,会对应于CUserRecordSet里面的一个CString类型的成员m_Name。 用这种方式的好处是不用针对不同的字段类型,以不同的参数形式调用GetFieldValue()函数来完成数据库里面的列数据的读取。5 系统实现5.1对所有的用户发送谁进入了聊天室及头像的加载CString userInfo;userInfo =log$;userInfo +=name;userInfo +=$;CString temp;temp.Format(%d,cu-IIndex); userInfo +=temp+$;m_ServerList.AddTail(cu);/返回值:第一个版本返回新插入的元素位置值/添加一个新元素或元素列表此列表的尾部。该列表可在操作前空pos=m_ServerList.GetHeadPosition();/GetHeadPosition 返回的是链表头元素的位置 while(pos!=NULL)infor=(CUserInformation *)m_ServerList.GetNext(pos);/ GetNext(pos) 如果该列表是通过为指针常量CObList访问,然后返回一个CObject的指针。这使得该函数只能用于一个赋值语句的右边,从而保护名单的修改 调用GetNext后pos的值就改变了,pos指向下一个元素 CString user;user =log$;user +=infor-IName;user +=$;CString he;he.Format(%d,infor-IIndex); user +=he+$;CString mes;mes += name+进入了聊天室!;send(infor-ISocket,userInfo,strlen(userInfo),0);if (infor-ISocket!=st) send(st,user,strlen(user),0);Sleep(175);send(infor-ISocket,mes,strlen(mes),0);AddListOnline(cu);GetDlgItemText(IDC_EDIT1,m_history);SetDlgItemText(IDC_EDIT1,m_history+rn+name+进入了聊天室!);CEdit *ce=(CEdit*)GetDlgItem(IDC_EDIT1);ce-LineScroll(ce-GetLineCount()-1);其中m_ServerList为一个CObList对象,cu为指向CUserInformation的一个指针。 AddListOnline函数为把用户对应的头像加到头像列表中。5.2 服务器自定义消息处理函数LRESULT CChatSeverDlg:OnServer(WPARAMwParam,LPARAMlParam)CUserInformation *cu=new CUserInformation();/CUserInformation为定义的存用户信息的类SOCKET st;char *p=NULL;CString stest;CString ste;CString qte;POSITION pos;CUserInformation *infor=NULL;int d;char buf10=0;CString name;CString pass;char s1024=0;switch(lParam)case FD_ACCEPT:st=accept(m_socketServer,NULL,NULL);return 0;case FD_READ:st=wParam;d=-1;recv(st,s,1024,0);stest=(char*)s;ste=stest.Left(4);d=ste.Com
展开阅读全文