收藏 分销(赏)

基于局域网的聊天软件的设计与实现.doc

上传人:仙人****88 文档编号:9356584 上传时间:2025-03-23 格式:DOC 页数:52 大小:1.16MB
下载 相关 举报
基于局域网的聊天软件的设计与实现.doc_第1页
第1页 / 共52页
基于局域网的聊天软件的设计与实现.doc_第2页
第2页 / 共52页
点击查看更多>>
资源描述
安徽工业大学毕业设计(论文) 安徽工业大学 毕业设计(论文)说明书 基于局域网的聊天软件的设计与实现 专 业 计算机科学与技术专业 班 级 计123 姓 名 -- 学 号 ---- 指导教师 --- 二〇一六 年 六 月 十 日  摘 要 如今网络的飞速发展,网络世界这一概念早已不再陌生,正是因为即时通讯软件的诞生,网络世界才蓬勃发展。即时通讯软件给人们提供了一个交流的平台,这种平台逐渐衍生发展成为一种特殊的社区,但是脱离这样的社区就会影响到人们的正常生活,工作和学习。随着通信,网络的整合,即时通讯软件将进一步发展成为新一代的通讯软件,有着巨大的发展前景。Na局域网聊天软件正是介于这样的发展背景之下开发而成。 本论文所设计的局域网聊天程序将采用软件工程学的设计流程,其所涉及专业技术主要包含socket网络编程,ODBC数据库编程技术,Windows MFC 程序设计技术,多线程机制。本程序将以VS 2012作为系统开发工具。此聊天程序将采用C/S模式即客户端/服务器模式。客户端和服务器、客户端和客户端之间均采用UDP进行通信。服务器主要负责储存局域网内所有用户的信息,当用户信息发生变化时通知所有客户端。此外服务器还要负责分配用户的惟一标识id。除此之外,服务器还能注销用户和群发系统消息。客户端具有用户注册、用户登录和向局域网内任何一个用户发送信息的功能。 关键词:局域网聊天;即时通讯;通信;群聊天。 Abstract Today, the rapid development of the network, the concept of the online world is no longer strange, it is because of the birth of instant messaging software, the online world was booming. Instant messaging software to provide people with a communication platform that gradually rise to become a special kind of community, but from such communities will affect people's normal life, work and study. With the integration of communications, networking, and instant messaging software will be further developed into a new generation of communications software, it has great prospects for development. Na LAN chat software it is under this context of development between developed. This paper is designed LAN chat program using software engineering design process, they involve expertise mainly comprises socket network programming, ODBC database programming technology, Windows MFC programming technology, multi-threading mechanism. This program will VS 2012 as a development tool. This chat program using C / S mode is a client / server model. It is used between the client and the server, client, and client UDP communication. The main server is responsible for storing information for all users within the LAN, to inform all clients when user information changes. In addition the server also responsible for assigning user unique identifier Uid. In addition, the server can log off users and mass system messages. Clients with user registration, user login, and send information to any user within the LAN. Key words: LAN chat;instant messaging; communication;group chat. III 目 录 摘 要 I Abstract II 1 系统概述 1 1.1程序简介 1 1.2系统实现技术 1 1.2.1 MFC窗口控件重绘 1 1.2.2 Winsock编程 2 1.2.3多线程编程 3 2系统分析 5 2.1需求分析 5 2.2可行性分析 5 3 系统实施 6 3.1系统实施 6 3.1.1软件开发工具的选择 6 3.1.2开发平台 6 3.1.3模式选择 6 3.1.4程序设计与调试 6 4系统详细设计 7 4.1系统功能设计 7 4.1.1主要功能描述 7 4.2.1网络通信的实现 8 4.2.2登陆验证模块 13 4.3用户界面设计 16 4.3.1 用户界面设计原则 16 4.3.2 登陆会员界面 16 4.3.3 注册会员界面 17 4.3.4已登陆界面 19 4.3.5表情与限制敏感词汇界面 20 4.3.6与个人进行私聊或者屏蔽个人界面 21 4.3.7公告界面 22 4.3.8密码修改界面 23 4.3.9系统设置界面 24 5系统测试 25 5.1测试的目的 25 5.2功能测试 26 5.3压力测试 26 总 结 27 致 谢 28 参考文献 29 附录 30 1 系统概述 1.1程序简介 NA即时通讯程序是基于windows下的聊天程序,采用Winsock实现网络通讯,其设计架构为集中式的P2P,即服务器为中心,所有相关的核心数据全部存放在服务器上,客户端只能按照规定的方式读取其数据。该软件主要采用UDP协议,但某些特殊情况也采用了TCP协议。比如,命令消息和聊天消息均基于UDP协议,而获取用户列表则采用的是TCP协议,两种协议的混用更能保证客户端与服务器通讯时的效率和准确性。NA实现了在局域网下进行局域网下的聊天室聊天和个人聊天功能,其组成部份是客户端和服务器两大部分。其中服务器部分进行对会员,公告的修改等功能,并即时相应客户端发送而来的命令,进行相关的数据读写,并返回客户端相应的命令消息。客户端部分则是实现用户的操作界面,实现用户间的聊天以及聊天室聊天等功能。 1.2系统实现技术 1.2.1 MFC窗口控件重绘 MFC(Microsoft Foundation Classes),是一个微软公司提供的类库(class libraries),以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。 的确,MFC给我们提供了很便捷的编程方式,我们几乎可以不需要写任何代码就能生成一个带有菜单,工具栏和视图的窗口,MFC也提供了丰富的控件类,在设计对话框的时候,我们也只需要直接将控件拖进对话框里,而不用写任何代码。 NA就是典型的MFC应用程序,采用了MFC对话框设计框架,但是为了设计一个友好美观的操作界面,仅用微软提供的控件类库达不到预期的效果,因此,就必须重新绘制其对话框和控件的界面。而正由于微软将这些控件封装得很好,对于要修改它的属性,派生一些美观的子控件难度就显得比较大。一般来说,实现对控件的重绘技术主要有子类化,自绘和重绘技术,由于MFC框架太过于标准化,因此实现这些技术也是有一定的难度,这必须要对框架的结构有一定的了解。NA采用了的窗体背景重绘,listctrl自绘,按钮贴图等方式实现了操作界面的美观。主要核心技术是GDI双缓冲绘图。双缓冲绘图就是将待绘制的图片保存到内存里,当需要绘制到屏幕上时,再一次性投递到设备描述表里,这样既避免了窗口重绘时的闪烁,又提高了绘制的速度和效率。BOOL CDC::CreatieCompatibleDC(CDC* pDC)函数用来创建一个兼容DC,即在内存里创建一个DC,以后的任何绘图所需的操作,如选用何种画笔,画刷,字体等,都将在内存中进行,而不是在真实设备上下文里。随后可以创建一张兼容位图,需要绘制的图像将,函数原型如下BOOL CBitmap::CreateCiompatibleBitmap(CDC* pDC,int nWidth,int nHeight)。最后需要将兼容DC里的东西投射到真实的DC里, BOOL BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc,DWORD dwRop )函数可以实现该功能,具体用法可参考MSDN。 对话框的绘制比较容易,MFC为对话框提供了OnPaint消息相应函数,但是在该函数下绘制并不能从根本上重绘对话框,因为该函数还会调用CDialog::OnPaint函数,在内部还会再去重绘背景,因此要实现完全意义上的重绘背景,就必须响应WM_ERASEBKGND消息,在消息响应函数里实现我们自己的绘制方法,然后直接返回TRUE,不再调用CDialog::OnEraseBkgnd()函数。为了实现像QQ那样的界面,必须将对话框的属性设置为None属性,即没有标题栏,因此只有自己去实现标题栏的功能。 CListCtrl重绘的方法有两种,一种是采用微软提供的OWNERDRAW属性,通过重载DrawItem虚函数来进行重绘。另外一种就是Custom-draw属性,通过定义自绘消息响应函数来进行重绘。两种方式有不同之处,前者需要对整个ListCtrl绘制,必须考虑到每一个item项的绘制情况。而后者相对比较简便,系统会在四个状态的时候通知重绘,这四个状态分别是绘制前,绘制后,擦除前,擦除后,我们就可以按照自己的需要去绘制,并且我们只用考虑其中一项item的绘制方法,就可以应用于所有项。NA采用了后者进行对列表控件的重绘,实现了好友列表控件,群列表控件类。 对于VC6开发环境,微软提供的通用button控件的外观从现在看来的确不太美观,无法实现动态状态的效果。那么因此就必须重新创建一个派生于CButton的按钮类,由于该类将应用于本软件的所有按钮控件,因此做成可贴状态图的按钮控件最为合适。状态分为移出按钮,悬浮按钮,按下按钮,禁用按钮四种状态,我们只需要提供相应的状态的Bitmap就可以。具体重绘方法就是采用前面提到的OWNERDRAW属性,重载虚函数DrawItem。而捕获鼠标的移入移出消息可以使用_TrackMouseEvent函数,通过设置TRACEMOUSEEVENT结构体的值来捕捉该消息。其移出消息对应的是WM_MOUSELEAVE,移入按钮消息是WM_MOUSEHOVER,分别定义其消息相应函数,这样就能实现状态的更替,再进行相应的绘制。 1.2.2 Winsock编程 Windows下网络编程的规范-Windows Sockets是Windows下得到广泛应用的、开放的、支持多种协议的网络编程接口。它实现了标准socket编成的函数,提供了一套属于windows下的套接子API。其通信的基础是套接字(Socket),一个套接字是通讯的一端。在这一端上你可以找到与其对应的一个名字。一个正在被使用的套接字都有它的类型和与其相关的进程。套接字存在于通讯域中。通讯域是为了处理一般的线程通过套接字通讯而引进的一种抽象概念。套接字通常和同一个域中的套接字交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序)。Windows Sockets规范支持单一的通讯域,即Internet域。各种进程使用这个域互相之间用Internet协议族来进行通讯(Windows Sockets 1.1以上的版本支持其他的域,例如Windows Sockets 2)。套接字可以根据通讯性质分类;这种性质对于用户是可见的。应用程序一般仅在同一类的套接字间通讯。不过只要底层的通讯协议允许,不同类型的套接字间也照样可以通讯。用户目前可以使用两种套接字,即流套接字和数据报套接字。流套接字提供了双向的,有序的,无重复并且无记录边界的数据流服务。数据报套接字支持双向的数据流,但并不保证是可靠,有序,无重复的。也就是说,一个从数据报套接字接收信息的进程有可能发现信息重复了,或者和发出时的顺序不同。数据报套接字的一个重要特点是它保留了记录边界。对于这一特点,数据报套接字采用了与现在许多包交换网络(例如以太网)非常类似的模型。其中TCP协议就是基于流套接字,而UDP协议基于数据报套接字,NA聊天程序主要基于UDP协议,而在特殊操作下又采用TCP协议保证其数据的可靠性。 在设计阶段,需分析该软件适用于什么样的地协议进行通讯,还必须分析该系统应该适合于何种套接字IO操作。目前,windows提供了多种套接字IO模型,如阻塞式IO,非阻塞式IO,事件IO,重叠IO(可提醒IO),完成端口等,每一种IO模型都具有自身的优势和缺陷,其中完成端口可以达到目前windows平台下最高IO性能。 由于是基于UDP协议,并且考虑到在同一时间处理得命令并不会很大的情况,服务器和客户端均采用基于非阻态的IO模型实现命令的传输。windows提供了一个CAysncSocke异步套接字类,它是基于非阻塞模型,对Socket函数进行了良好的封装,CAsyncSocket::Create()有一个参数指明了你想要处理哪些Socket事件,你关心的事件被指定以后,这个Socket默认就被用作了异步方式。CAsyncSocket的Create()函数,除了创建了一个SOCKET以外,还创建了个CSocketWnd窗口对象,并使用WSAAsyncSelect()将这个SOCKET与该窗口对象关联,以让该窗口对象处理来自Socket的事件(消息),然而CSocketWnd收到Socket事件之后,只是简单地回调CAsyncSocket::OnReceive()等虚函数。所以CAsyncSocket的派生类,只需要在这些虚函数里添加发送和接收的代码。因此介于微软提供的强大类方法,就很容易实现数据的通信。 1.2.3多线程编程 多线程编成是网络编成的基础,几乎所有的网络编程都将涉及到多个线程的数据传输,并且还要实现界面和数据处理互不影响。多线程编成虽说是基础,但是却是一个难点,因为线程同步的确比我们想象的复杂得多。要理解多线程编成就必须从以下几个方面理解:一、操作系统多任务概念;二、线程和进程的联系与区别;三、如何创建并管理销毁一个线程;四、何谓线程同步,怎样同步。 什么是多任务概念?用通俗易懂的话就是几个运行的任务“同时”进行,比如Windows就是典型的多任务操作系统,我们可以同时进行听歌,打游戏,聊QQ,在基于这种理念的系统感觉就像所有的程序在同时运行一样。但实际上在单CPU的机子上,这些程序并不是同时在运行(即便是在多CPU的电脑上,也不可能所有程序同时运行),所有的程序都以某种调度算法,按照优先级,依次获取CPU时间,每当一个程序获得CPU时间后,它就会得到运行,而当运行一段时间后,操作系统会将其暂停,再接换新的线程来运行。由于电脑的速度很快,这种非并发的模式却可以达到类似并发的效果。实际上,正如前面所说,操作系统并非是给某一程序分配时间片,准确的说是给这个程序里的某一线程分配了时间片。因此,在多任务操作系统中(若有线程的话),线程将是运行的最小单位。 在windows系统中,进程和线程是最为重要的两个概念,因为整个系统就是基于进程和线程的。那么进程和线程有什么区别和联系呢?进程实际就是一个运行的程序,该程序有自己的堆栈空间,有自己的线程(至少有一个主线程),并且可以创建其它进程或线程。有一个概念容易搞错,就是进程是否能获得CPU时间片?实际上,进程是无法获取CPU时间片,只有该进程里的线程才能,所以说,真正执行代码的是线程,而进程只能管理线程,管理内存等。 在NA程序里,涉及了诸多对线程的创建,管理和销毁工作,特别是在服务器部分,为了保证数据响应的即时性,必须对每一个处理创建一个线程。常用的创建线程函数为CreateThread和_beginthreadex,两函数功能几乎一样(在某些特殊地方,两者用法需注意,推荐用后者),在创建前必须定义一个按照线程函数原型的函数,将其地址传给创建线程函数,让操作系统知道即将从哪个地方运行线程。除此之外,还可以传递参数,供线程使用。若创建成功,该函数会返回一个HANDLE,这个句柄标示了刚创建的线程内核对象,当线程创建成功后,必须调用CloseHandle函数将其关闭,这是因为如果不关闭该内核句柄,当线程退出后,操作系统并没有销毁该线程,造成资源浪费,这是因为获取一个实内核句柄都会增加内核使用计数,只有当该内核对象的使用计数为0时,才会销毁该内核对象,线程也是如此。常用的销毁线程函数是ExitThread,TermelateThread函数,但推荐使用函数返回的方式结束进程,因为操作系统会自动调用ExitThread函数,并回收分配的内存资源。 由于多个线程在同时运行的时候,会对共享数据进行访问或修改,那么就必须要注意数据同步,windows给我们提供了多种数据同步的方法,比如基于用户模式的原子锁,临界区,SlNA读写锁等,还有基于内核模式的内核对象,如互斥对象,事件对象,信号量,条件变量等。在NA聊天程序中,最常用的是临界区,原因是基于用户模式,同步效率快,服务器可以进行更多的操作,其次还用到了事件对象,由于临界区太过单一的功能,并不能满足有些数据同步的需要,因此用到了功能强大的事件对象,在MFC中,事件对象被封装成了CEvent类,在SDK下,可以用调用CreateEvent API函数创建一个事件对象。 2系统分析 2.1需求分析 注册会员。任何非会员都可以登陆注册界面注册一个自己的NA账号,今后就可以通过该帐号登陆NA进行聊天。添加好友。会员可以通过查询NA会员,添加自己的好友,成为好友后,两会员便可以自由的通讯,还可以实现后续的多种功能。 好友聊天。会员可以与自己所有的好友进行聊天。 群聊天。群里的所有成员的聊天都是公开的,即该群所有成员能看到群里所有的发送的消息。 2.2可行性分析 本软件只是做开发学习之用,所以不必考虑成本问题。由于在软件设计之前,已经做好了需求分析以及充分的前期准备工作。确定了本程序的平台为Windows,将要使用udp socket进行网络通信,此程序的开发系统为VS2012。而VS2012开发Windows程序的能力有目共睹的,并且对计算机要求不高,大众的电脑即可安装并比较流畅运行,因此此程序在开发的技术可行性上是完全行得通的。 3 系统实施 3.1系统实施 3.1.1软件开发工具的选择 本软件采用VS2012,MFC程序框架进行开发。VS2012是Microsoft公司推出的一个基于Windows系统平台、可视化的集成开发环境,它的源程序按C++语言的要求编写,并加入了微软提供的功能强大的MFC(Microsoft Foundation Class)类库。MFC中封装了大部分Windows API函数和Windows控件,它包含的功能涉及到整个Windows操作系统,同时也提供了强大的调试器,具有查看堆栈,汇编代码等多种功能。虽然在目前而言VC6在整个VS系列里只能算老产品,但其功能仍然很强大,足够满足于本软件的真个开发。本软件涉及到数据库的操作,因此服务器部分采用SQL Server数据库。 3.1.2开发平台 基于上面软件开发工具的选择,并考虑到本系统的性能要求,本系统采用Windows 7中文版作为开发、测试和运行平台。硬件选择Pentium 4以上,2g以上内存,50G以上硬盘。 3.1.3模式选择 本软件是基于C/S模式,采用集中式P2P思想。在客户机/服务器网络通讯中,服务器是网络通讯的核心,而客户机是网络通讯的基础,客户机依靠服务器获得所需要的网络资源,而服务器为客户机提供网络必须的资源。它的优点是:(1) 应用服务器运行数据负荷较轻。(2)数据的储存管理功能较为透明。缺点是高昂的维护成本且投资大。 3.1.4程序设计与调试 程序设计与调试主要经过了以下几个步骤: (1)总体框架的建立,即数据库的建立; (2)模块的建立; (3)窗口的设计; (4)代码的编写; (5)模块的测试; (6)总体测试。 4系统详细设计 4.1系统功能设计 4.1.1主要功能描述 1.服务器功能描述 (1)登陆验证功能:当客户端发送了登陆命令后,服务器会验证传入的帐号和密码是否为已注册的会员,并返回验证后的信息。 (2)发送公告:服务器端可以进行公告发送,即所有人都可以看到的公示。 (3)用户管理:可以对用户进行删除。 (4)信息过滤:一些敏感词汇设置自动屏蔽。 (5)密码修改:修改服务器(管理员)密码。 2.客户端功能描述 (1)会员登陆:要想使用NA进行聊天,就必须在登陆界面进行会员登陆,客户端会发送验证的帐号和密码给服务器,若验证通过,就能登陆进该帐号,进行后续的服务功能。 (2)注册会员:若第一次使用NA,没有NA帐号的话,可以在登陆界面下进行注册,客户端会将待注册的信息发送给服务器处理,注册成功,即可使用。 (3)聊天室聊天:在登陆后界面,所有用户可以在聊天室进行聊天。 (4)对用户进行私信: 对聊天室在线用户可以进行私信,即只针对个人的聊天。 (5)退出登陆:NA会员退出登陆时将发送命令给服务器,服务器获得退出命令后将更新在线列表。 (6)个人公告:可以进行修改个人公告,在管理员中可以进行设置公告内容。4.2重要模块的具体实现 4.2.1网络通信的实现 1.基于UDP的数据发送与接收 图4.1服务器与客户端通信模型图 图4.2服务器与客户端的通信图 (1)服务器端的数据接收 服务器基于UDP的数据发送与接受主要采用的是MFC提供的CAsyncSocket类,该类提供了基于异步非阻塞式的IO操作。NA程序里根据CAsyncSocket派生了一个CNASocket类,服务器用该类进行数据的发送与接收,并将接收后的数据按照命令类型分发给各处理子模块。创建该类在CNAessageDlg对话框类(服务器运行的主窗口)的OnInitDialog函数里,每当程序运行时都将自动调用该函数,进行对话框的初始化操作,这是将是创建CNASocket类的最佳场所。该对话框类提供一个内部接口函数BOOL CNAessageDlg::CreateUDPSocket(),用于创建CNASocket类。当CNASocket类创建成功后,将其指针保存在对话框里保护类型成员变量里CNASocket* m_pSocket,方便以后的使用。CNASocket类重载了虚函数OnReceive用来接收网络信息,该函数是一个系统自动调用的消息相应函数,每当系统发现该套接字的接收缓冲区里有数据的时候,将调用该函数,那么我们就可以在该函数里,调用RecvFrom或Recv来获取数据。由于正是考虑到基于命令的信息传输,接收缓冲区里不一定时刻都有数据到来,那么采用了基于消息响应的异步套接字类。在OnRecevie函数里,可能同时会有多个数据包到来,若按照每到一个数据包进行解析和分发,将可能延误整个接收处理过程,造成接收缓冲区溢出,丢失大量数据包,因此NA在处理接收来的数据时,会先将接收到的数据包加入到一个数据包队列里面去,用另一个独立的接收线程读取该队列里的数据包,再根据其命令类型分发处理(在NA里封装了一个CPacket类,用来存储各种接收到的数据包)。在接收线程里(如图4.6),会不断的判断数据包队列里是否有数据到来,若没有数据,则进入等待(NA里使用的时事件内核对象,当现在数据包队列里没有任何数据时进入睡眠状态,这样可以降低该线程因反复执行判断循环而造成占用大量CPU时候,当OnRecevie里接收到一个数据后,就会将触发事件对象,唤醒接收线程)。若发现有数据到来,则分析数据包类型,创建相关的处理线程执行相关的处理操作,这样可以在同一时间同时处理多个任务请求,提高了服务器的工作效率。程序执行流程图如下: 图4.3基于UDP的接收数据的程序流程图 图4.4接收线程程序流程图(服务器端) (2)客户机端的数据接收 客户端的接收流程与服务器大致相同,同样将UDP发送与接收封装到一个CNASocket类里(这个类与前面的CNASocket不是同一个)。在程序启动后同样会在OnInitDialog里调用一个原型为BOOL CNADlg::CreateSocket(CString szIP, UINT16 nPort)的函数创建CNASocket对象,接收原理与服务器接收相同,同样要提供一个数据包队列,同样要单独创建一个接收线程进行数据包的解析与分发,唯一不同的是处理后的数据包并不单独创建线程进行处理,而是通过发送消息,将处理分发到各对应的对话框里,自行处理。因为客户端主要由各种类型的窗口构成,而窗口本身就是一个线程,因此不会阻塞到接收线程的正常运行。(接收数据流程图参考图4.6) 图4.5接收线程程序流程图(客户端) (3)服务器端的数据发送 服务器端的数据发送相对比较简单,除了在获取聊天室成员时是基于TCP协议的数据传输,其余的均是基于UDP协议。因此在CNASockt类中封装了一个int CNASocket::SendToClient(CPacket& packet)成员函数,在需要发送数据的时候(服务器端大多在处理线程里回复数据给客户端)直接调用该公共成员函数即可。 (4)客户机端的数据发送 在客户端的CNASocket中和服务器端大致一致,是用来向服务器发送数据,函数原型为BOOL CNASocket::Send Info(void *lpData, int nBufLen)。 2.TCP连接 为了保证数据的可靠性,对于连续发送大量有序的数据包,采用UDP协议并不保险,因此在必要的时候,也必须采用TCP协议来支持数据的稳定和可靠性。在NA里,由于获取聊天室成员时时会连续发送大量的数据,因此此时最好使用TCP协议进行数据通信。 图4.6 TCP接收请求处理流程图(服务器端) 在服务器端,NA同样是在主窗口的OnInitDialog里创建TCP连接,同样提供了一个内部接口函数BOOL CNAessageDlg::CreateTCPSocket()来创建TCP连接。由于有两种情况需要用到TCP连接,因此分别设计了BOOL CreateTcpSocketToGetLoginUserInfo()和BOOL CreateTcpSocketToGetGroupMemberInfo()这两个函数完成对应的TCP创建工作。由于考虑到同时将会有多个获取好友列表或群成员列表的请求,为了提高服务器的响应速度,也应该为获取好友列表和群成员分别创建一个线程来accept客户端的请求连接。为了充分发挥多服务器多CPU的特点,在accept请求后服务器会创建一个线程池来管理每个处理线程,线程池的最大线程数应该等于CPU的个数,这个是基于最大化提高CPU处理效率的特点而确定的,这是因为少一个线程,不能发挥到所有CPU的并发优势,若多一个线程,同样会等待CPU时间片,所以没有必要。当处理线程执行结束后,不应该立即退出,这样会由于反复创建和销毁线程而浪费大量的CPU时间和资源。正确的做法应该在完成处理后,查询当前是否有TCP连接请求未处理,若有就读取该请求数据进行处理,这样就避免了销毁和创建线程时浪费的时间,这个思想是基于完成端口的内部实现原理而设计的。 图4.7 TCP接收处理线程执行流程图(服务器端) 4.2.2登陆验证模块 图4.8登陆验证模块实现原理图 NA的会员登陆采用了UDP和TCP相结合的方式,涉及到地的对话框切换较多,登陆过程较为复杂。用户输入帐号和密码,点击登陆后,会响应CNADlg主窗口的OnLogin函数,该函数里创建了一个登陆对话框CNALoginedDlg,该对话框主要起到一个会员登陆,并获取登陆信息的作用。创建该对话框1秒之后,会开始向服务器发送会员验证包,NA定义的命令包主要采用结构体的方式,每一个命令包都含有一个命名包头和命令包数据,其中头部被定义为: struct NA_Header { UINT32 cmd; UINT16 seg; UINT16 id; UNT32 reserved; } 该结构体的cmd字段便是命令,所有的命令被定义为宏,在NA_Protocol.h文件里。其中会员登陆的命令为NA_LOGIN,其值为0x0001,其他的命令将在后面会提到。登陆所发送的数据包被定义为了一个名为login_info的结构体(所有网络通信用的结构体均定义在了structinfo.h文件里),该结构体除了包含命令头部外,还包含了待登陆的账号和密码。客户端发送了会员登陆命令后,便等待服务器的回应了,若等待超时便提示连接失败。 在服务器部分,通过前面描述的udp的接收流程,服务器在接收到登陆请求后,最终会创建一个LoginThread线程来进行登陆验证。在该线程中服务器首先读取数据库进行验证,所有的数据库操作被封装到了CSql类里,该类提供了一个公用方法,Excute,具体用法见代码。验证后将返回信息给客户端,在NA里,几乎所有由server回应给客户端的数据包结构体被定义为XXX_back的名字,如登陆回应,用到了login_back结构体。若服务器发现验证成功,并且当前该会员没有在其他处登陆过,那么就通知该会员所有的在线好友的上线通知,这里调用了CNASocket::NotifyMember函数。 图4.9客户端验证登陆流程图 当服务器执行完登陆处理线程后,客户端进入接收流程,若验证失败,根据错误信息进行错误提示,若发现验证成功,便开始获取登陆信息。NA在获取聊天室列表的时候用到了TCP短连接,客户端会创建一个RecvInfoThread线程去接收数据,在线程内部会创建 TCP套接字连接服务器,并依次获取群信息和好友信息。在获取完登陆信息后,随后便创建登陆后的用户界面CNALogonDlg对话框。在初始化该对话框时,会将之前获取的信息加入到两个CNAListCtrl里面(登陆界面的列表控件),随后会向服务器发送离线消息请求,服务器接收到消息后,会将保存在数据库里的离线消息发送给该会员。当客户端接收完离线消息后,登陆过程完毕。 4.3用户界面设计 4.3.1 用户界面设计原则 本软件界面均以对话框为基础,以简洁,大方的外观,便捷,简单的操作为设计目的。具体设计原则如下。 1. 由于本软件个人毕设使用,应将界面设计得大方,简洁。 2.界面统一采用浅蓝色为主色调,白色为辅色,给人一种清新,愉快地感觉。 4.为了更方便用户的使用,所有功能直接清晰地在界面就能看到。 4.3.2 登陆会员界面 在此界面可以进行注册及登录。 图4.14 登陆界面图 4.3.3 注册会员界面 新用户注册界面如下图: 图4.15 注册用户界面 在此界面先输入用户名,然后输入密码,再次确认密码,确认密码是需要两次密码相同才可以,如果不同会发生注册不成功。在全部输入正确后点击确定按钮即完成注册。 注册成功界面: 图4.16注册成功界面 注册失败界面: 图4.17 注册失败界面 如果你注册的用户名已经有人用过,会发生错误提示,因为用户名相当于唯一识别id,每个人用用户名进行登录操作,如果用户名重复会发生紊乱。 4.3.4已登陆界面 图4.18已登陆界面图 登陆进去后显示如图界面,在此界面可以看到公告和在线用户,同时此界面是进行聊天界面,在此界面可以进行私聊。发送时仿照qq完成的可以按Ctrl+Enter进行发送。系统公告可以自行添加。 4.3.5表情与限制敏感词汇界面 图4.19 表情和限制词汇 可以发送表情,可以修改字体可以限制敏感词汇,这些模块都是在我的导师的指导下添加的。 4.3.6与个人进行私聊或者屏蔽个人界面 图4.20私聊或者屏蔽他人聊天界面 可以在在线用户中进行私聊或者屏蔽某个人, 看到在线用户时点击右键会弹出‘与其私聊’和‘屏蔽此人’两个按钮,单击任意一个即可完成相应功能。 4.3.7公告界面 图4.21设置界面 在此界面可以进行个人公告的设置,公告标题及内容自己进行填写,填写完成确认无误后点击提交即可,若提交成功会弹出相对应的界面。 提交成功: 图4.22提交成功界面 4.3.8密码修改界面 图4.23密码修改界面 此界面可以进行密码修改,先输入旧密码,旧密码要确保正确,然后输入新密码和确认密码,确认密码要和新密码一致,点击应用,后台验证旧密码一致后新密码即成功使用,重置按钮相当于全部删除,避免了每个进行删除的麻烦。 4.3.9系统设置界面 图4.24 设置界面 在此界面可以进行系统设置,即所显示的每个功能,闪烁功能是仿照qq完成的。 第 24 页 共 45页 5系统测试 5.1测试的目的 如果测试的目的是为了尽可能多地找出错误,那么测试就应该直接针对软件比较复杂的部分或是以前出错比较多的位置。如果测试目的是为了给最终用户提供具有一定可信度的质量评价,那么测试就应该直接针对在实际应用中会经常用到的商业假设。 在谈到软件测试时,引用Grenford J. Myers在《The Art of Software Testing》一书中的观点: (1)软件测试是为了发现错误而执行程序的过程; (2)测试是为了证明程序有错,而不是证明程序无错误; (3)一个好的测试用例是在于它能发现至今未发现的错误; (4)一个成功的测试是发现了至今未发现的错误的测试。 这种观点可以提醒人们测试要以查找错误为中心,而不是为了演示软件的正确功能。但是仅凭字面意思理解这一观点可能会产生误导,认为发现错误是软件测试的唯
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传
相似文档                                   自信AI助手自信AI助手

当前位置:首页 > 学术论文 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服