基于java即时聊天系统的设计与实现

基于java即时聊天系统的设计与实现

ID:8317651

大小:764.50 KB

页数:76页

时间:2018-03-19

上传者:U-5649
基于java即时聊天系统的设计与实现_第1页
基于java即时聊天系统的设计与实现_第2页
基于java即时聊天系统的设计与实现_第3页
基于java即时聊天系统的设计与实现_第4页
基于java即时聊天系统的设计与实现_第5页
资源描述:

《基于java即时聊天系统的设计与实现》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库

本科毕业设计(论文)基于Java即时聊天系统的设计与实现学号:05学生姓名:指导教师:所在学院:计算机科学技术学院所学专业:计算机科学与技术专业2016年6月 摘要伴随着互联网的高速发展,产生了一系列与互联网相关的新鲜事物,即时聊天系统就是其中最具代表性的产物。即时聊天系统经过不断地发展,凭借其迅速、便捷、即时的特点,逐渐成为一种重要的信息交流工具,受到越来越多的网民的青睐。即时聊天系统开发主要包括两个方面:即时聊天系统服务器端设计、即时聊天系统客户端设计。即时聊天系统服务器端设计主要通过Socket套接字建立服务器,服务器能够读取和转发从客户端发来的信息,并且能够刷新用户列表。即时聊天系统客户端设计主要通过与服务器建立连接,从而使服务器端与客户端的信息进行交流。在这里,网络通信机制原理得到了运用,通过直接继承Thread类来建立多线程。同时,开发中利用了计算机网络编程的基本理论知识,如TCP/IP协议、客户端/服务器端模式(Client/Server模式)、网络编程的设计方法等。在网络编程中利用流来实现信息的交换,从而读取和发送信息。即时聊天系统采用myeclipse为基本开发环境和java语言进行编写,通过不断修正和改进初始原型系统,直至此系统完全可行为止。关键词:即时聊天系统;套接字;JavaII AbstractAlongwiththehigh-speeddevelopmentofInternet,producedaseriesofnewthingsrelatedtotheInternet,instantmessagingsystemistheproductofoneofthemostrepresentative.Instantmessagingsystemthroughconstantdevelopment,withitsfast,convenient,real-timecharacteristics,becominganimportantcommunicationtool,getthefavourofagrowingnumberofInternetusers.Instantmessagingsystemdevelopmentmainlyincludestwoaspects:instantmessagingsystemserverclient,instantmessagingsystemdesign.InstantmessagingsystemdesignmainlythroughtheSocketserverSocketserver,theservercanreadandforwardfromtheclient'sinformation,andbeabletorefreshtheuserlist.Instantmessagingsystemdesignmainlybytheclientandtheserverconnectionisestablished,whichmakestheservertocommunicatewiththeclient'sinformation.Here,theprinciplehasbeenusingnetworkcommunicationmechanism,throughdirectinheritanceforbuildingamultithreadedThreadclass.Atthesametime,theuseofcomputernetworkprogramminginthedevelopmentofthebasictheoryofknowledge,suchasTCP/IPprotocol,Client/Servermode(Client/Servermode),networkprogrammingdesignmethod,etc.Usingflowinnetworkprogrammingtoachievetheexchangeofinformation,soastoreadandsendinformation.InstantmessagingsystemusingmyeclipseasthebasicdevelopmentenvironmentandtheJavalanguagetowrite,byconstantlyrevisedandimprovedtheinitialprototypesystem,untilthesystemiscompletelyfeasible.Keywords:Instantmessagingsystem;socket;JavaII 目录摘要IAbstractII第1章绪论11.1课题背景11.2国内外发展现状11.2.1国外发展现状11.2.2国内发展现状11.3开发目的和意义21.4系统设计的思想2第2章方案论证32.1方案分析32.2可行性分析32.2.1经济可行性32.2.2技术可行性42.2.3操作可行性42.2.4法律可行性42.3方案的确定42.4系统设计的相关技术4第3章需求分析83.1系统基本功能描述83.2系统需求分析83.3数据流图83.4数据字典103.5用例图12第4章系统概要设计144.1系统总体流程图144.2系统功能模块划分15第5章系统详细设计与实现185.1系统设计与实现185.1.1注册模块185.1.2登录模块205.1.3聊天模块225.1.4后台管理模块255.1.5其他功能实现2871 5.2数据库设计31第6章软件测试与结果分析386.1软件测试386.1.1白盒测试386.1.2黑盒测试386.1.3系统测试386.2测试方法与总结396.2.1测试方法396.2.2测试总结40结论41致谢43参考文献44附录4571 第1章绪论1.1课题背景人类社会在不断的发展,从原始社会发展到如今高度发达的文明社会,离不开人类的团结协作及创造力,而交流便是人类在发展过程中至关重要的一项技能。在人类漫长的发展过程中,交流的方式也在不断更新变化。从最早的交流方式——直接交流(语言、文字等),到后来利用介质的交流方式——间接交流(飞鸽传书、烽火狼烟等),再到近现代利用工业革命的成果,创造出了远程交流方式(电报、电话等)。而到了上世纪末,随着计算机技术和网络技术的高速发展,诞生了一种新型交流方式——即时聊天系统。即时聊天系统在沟通、协作方面有着其它交流方式无法比拟的优势,它凭借方便、快捷、实时等特点得到了越来越多人的青睐。本课题研究的就是基于Java语言的即时聊天系统。即时聊天系统是为了满足各用户之间进行即时的信息交流而设计的一套系统,作为一种新型的通信和交流工具,即时聊天系统具有极其广泛的发展前景。本系统的主要特性是能动态、实时的完成信息的传递,同时具有高效的交互性,更有效的处理客户请求,同时维护和更新也更加简易。本文接下来会依次介绍即时聊天系统运行所需的环境及其工作流程和各个功能控件的工作原理,并且文中提供了部分程序源代码。1.2国内外发展现状1.2.1国外发展现状当今国际上对网络通信系统研究的较好的公司有:思科,Sun,Ms等公司,思科主要研究的是底层的传输;MS,Sun公司研究的是应用层。其中MS公司凭借其在操作系统的垄断地位,为了在网络的发展中取得先机,采用了各种各样的手段。但是,其捆绑的msn,无论从功能上,还是技术上来说,都不算是非常先进的。这让人想起了当年的网景公司,网景只是生不逢时。MS不择手段的想打跨网景,可见其对网络的重视。如今,Sun公司在网络应用上捷足先登,凭借着Java,Sun在网络的应用上领先于MS。微软,想用同样的办法搞跨对手,因此它拿出了Visualc#来对抗Java。这些都是在应用层面的开发工具,应用层上的产品就更显种类繁多。ICQ几乎是国际上通用的即时通信工具,由于在我国它的应用不是很广,所以其原理也很少被介绍。Msn,是MS的产品,同样在国内没什么市场,所以对其原理也很少被讨论过[1]。1.2.2国内发展现状71 国内在应用层上的网络应用软件目前发展异常的火爆,因为我国有着网络应用的最大的市场。现在国内网络的基础性建设发展迅速,应用软件也层出不穷。不少厂商分别推出了自己的IM,如腾讯QQ、阿里旺旺、新浪UC、移动飞信等,这些都是我们所熟悉的PC端的即时通讯软件。随着智能手机、平板电脑的普及,一些移动端的即时通信系统也如雨后春笋般涌现出来,如小米公司的米聊,腾讯公司的微信,还有年轻人之间很流行的陌陌、游戏玩家常用的YY语音等。这些软件本身功能也越来越丰富,远远超出了单纯的即时聊天系统的范畴。现在的即时通信系统不仅仅是人们的沟通工具,还成为了人们利用其进行电子商务、工作、学习等交流的平台。1.3开发目的和意义在当今社会,不管是个人用户还是企业用户,对沟通的需求总是在不断地发展。传统的沟通交流方式如电话、传真、邮件等已经不能完全满足人们学习、工作、生活的需要。随着计算机软件、计算机网络和移动通信技术的发展融合,集方便、廉价、快捷、实时等优点于一身的即时聊天系统可以说是继电子邮件、万维网之后,互联网上最具有杀伤力的应用。很难想象一台个人电脑没有安装像QQ这样的即时通讯软件。虽然即时聊天系统设计的初衷是聊天,但正如前面所说,其功能已经超出了聊天的范畴,随着企业即时通讯工具(EIM)的出现,IM系统更是成了企业信息发布、资源共享、问题探讨和网络营销的一把利器。通过现有的技术,企业完全可以摒弃通用的免费的即时通讯系统,转而根据自己企业的需求定制开发自己专属的内部即时通讯系统,以实现更好的管理,提高员工的工作效率。我们的生活中沟通无处不在,即时聊天系统这类广泛使用的基础软件的研究开发意义深远。对于个人用户而言,能够实现好友即时通讯,传递实时信息,让用户随时随地都可与好友保持畅快有效的沟通。 对于企业用户而言,能够实现建立员工交流平台,统一信息发布平台,减少运营成本,促进企业办公效率。 商业即时通讯系统的功能越来越多样化,一些功能也很新颖,如现在流行的语音对讲功能。本系统不比商业系统,没有考虑过多的复杂性,主要实现了基本的通讯功能,以满足学习研究之用。1.4系统设计的思想基于Java技术的聊天系统主要是探索如何在Java技术下能够实现即时聊天的一些基本功能:用户注册,用户登录,查找其他用户,添加删除好友,添加个性签名,发布和接收系统消息,实现一对一聊天,能够发送表情等功能。论文的设计主要采用了两种研究方法:一是文献资料研究的方法。在研究聊天系统现实中,本人通过图书馆、电子图书馆学习了Java语言中的一些编程技术;二是理论与实际相结合,既然掌握了技术与方法,那么就应该快速的进行实践,在软件的设计过程中,才能够理解到理论与现实的差距,遇到棘手问题,应该快速查阅资料快速攻破。71 第2章方案论证2.1方案分析经过认真的研究与分析,同时综合各种计算机高级语言的特征和适应范围,最终决定选择纯面向对象的Java语言来完成即时聊天系统的设计。对于本系统的设计,可以采用C/S和B/S两种不同的模式。在数据库方面,Hibernate和MyBatics都有着很强大的功能,而且Mysql和Oracle也有着不同的优缺点。综上所述,可以得到以下两个方案。方案一:C/S模式+Hibernate+OracleC/S(Client/Server)结构,即大家熟知的客户机和服务器结构,其优点是能充分发挥客户端PC的处理能力,很多工作可以在客户端处理后再提交给服务器。对应的优点就是客户端响应速度快。而且Hibernate对数据库进行的是重量级的封装,对整个运行速度不会很慢。而且Oracle体积很大一般在几个GB的安装包,运行时它的内存一般是几百兆,但是Oracle集成的功能非常强大。方案二:B/S模式+MyBatics+MysqlB/S(Browser/Server)结构即浏览器和服务器结构,它是随着Internet技术的兴起,对C/S结构的一种变化或者改进的结构。在这种结构下,用户工作界面是通过WWW浏览器来实现,极少部分事务逻辑在前端(Browser)实现,但是主要事务逻辑在服务器端(Server)实现,形成所谓三层3-tier结构。这样就大大简化了客户端电脑载荷,减轻了系统维护与升级的成本和工作量,降低了用户的总体成本(TCO)。MyBatics是对数据库的轻量的一个封装,但是sql语句需要自己来设置,配置在xml文件中。而MYSQL非常小,一般几十兆,对主机的内存占用也不是很大,安装方便。2.2可行性分析开发任何一个系统,都是要受到时间和资源等的一些限制。因此,在每一个系统开发之前,都必须要进行可行性分析,这样就可以减少软件开发所带来的风险,也大大的避免了在物力、人力和财力上的浪费[2]。本系统的可行性分析应包括四个方面:经济可行性、技术可行性、操作可行性和法律可行性。2.2.1经济可行性71 计算机网络已经普及,因此在网络设备上不需要进行大的投入。本系统如果采用一个MySQL数据库服务器,相对于Oracle数据库服务器成本偏低。同时,本系统能够让人们的交流更加便捷,其带来的间接效益远远超过了其开发成本,所以在经济上本系统的设计是具有完全的可行性的。2.2.2技术可行性此系统可以使用MySQL存储用户信息,由于MyBatics对Sql语句的封装小,这会增加开发过程中的代码量,并且,Oracle运行时很占用内存,它集成了很多功能,而且我们用很多功能用不上,所以MySQLl是很满足我们的需求的。MySQL作为一种关联数据库管理系统,将数据保存在不同的表中,是一个安全度高、可靠性好的并且能够支持面向对象设计的数据库系统。同时,MySQL开放源码,速度快、总体拥有成本低等特点Error!Referencesourcenotfound.。并且在易用性、可维护性、灵活性等方面也很好。采用JDBC技术对其进行增删改查,使用套接字来实现网络上客户和服务器之间的连接,同时采用Hibernate框架来管理Java类到数据库表的映射(包括从Java数据类型到SQL数据类型的映射),并且提供数据查询和获取数据的方法。所以从技术角度来看本系统的设计是具有完全的可行性的。2.2.3操作可行性一方面可以让本地机同时作为客户端和服务器实现一台机器上的即时通讯。另一方面,只要一台以上计算机连接在同一个局域网内,并且在作为客户端机器的本系统中设置需要连接的作为服务器端机器的IP地址,本系统就可以实现局域网通讯,所以操作上完全不存在问题。如果要实现internet上通讯,理论上只需要将服务器端运行在一个有固定IP的公网上就可以。2.2.4法律可行性本即时聊天系统的开发,不会侵犯到别人的专利版权,也不违反国家的相关规定,所以在法律上来说也是可行的。2.3方案的确定根据以上的分析和总结,很显然方案一更适合我们的完成系统设计。因此,我们使用方案一来进行项目的开发。2.4系统设计的相关技术本即时聊天系统是基于Java语言的,采用C/S结构,使用MySQL存储用户信息,采用JDBC技术对其进行增删改查,使用套接字来实现网络上客户和服务器之间的连接,同时采用Hibernate框架来管理Java类到数据库表的映射,并且提供数据查询和获取数据的方法。71 1、Java语言Java是一种通过解释方式来执行的语言,其语法规则和C++类似。同时,Java也是一种跨平台的程序设计语言[3]。用Java语言编写的程序,可以运行在任何平台和设备上,如跨越IBM个人电脑、MAC苹果计算机、各种微处理器硬件平台,以及Windows、Unix、OS/2、MACOS等系统平台,真正实现“一处编写,到处运行”。Java非常适合于企业网络和Internet环境,并且已成为Internet中最具影响力、最受欢迎的编程语言之一。与目前常用的C++语言相比,Java语言简洁得多,而且提高了可靠性,除去了最大的程序根源错误,此外它还有较高的安全性,可以说它是有史以来最为卓越的编程语言。Java语言编写的程序既是编译型的,又是解释型的。程序代码经过编译之后转换为一种称为Java字节码的中间语言,Java虚拟机(JVM)将对字节码进行解释和运行。编译只进行一次,而解释在每次运行程序时都会进行。编译后的字节码采用一种针对JVM优化过的机器码的形式保存,虚拟机将字节码解释为机器码,然后在计算机上运行。Java语言的特点包括:简单、面向对象、分布性、可移植性、解释型、安全性、健壮性、多线程、高性能、动态。2、MyEclipse简介MyEclipse,是基于Eclipse开发的功能强大的企业级集成开发环境,主要用于Java、JavaEE以及移动应用的开发。据官方介绍,诸如三星、IBM、戴尔、惠普、花旗集团、西门子、斯坦福大学、波音公司等知名机构均使用MyEclipse进行Java、JavaEE开发,80%以上的全球财富100强企业均是MyEclipse的用户。MyEclipse提供了对UML、Ajax、Web、WebServices、J2EE、JSP、XML、Struts、JSF、JavaPersistence、EJB、扩展数据库以及各种应用服务器的集成支持[4]。MyEclipse也全面支持各种主流的第三方框架,让你能够快速高效地进行开发工作。此外,MyEclipse还全面支持各种基于Eclipse平台的插件,允许你自由定制或扩展个性化功能。MyEclipse全面支持Eclipse开源平台的所有功能特性,如果你熟悉Eclipse,那么你能够轻松地上手MyEclipse,包括熟悉的Eclipse快捷键,而且使用MyEclipse完成某项任务往往要比使用Eclipse更加快速、简单[5]。3、Oracle简介 OracleDatabase,又名OracleRDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。它是在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是目前世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的适应高吞吐量的数据库解决方案。 ORACLE数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构71 的数据库之一。比如SilverStream就是基于数据库的一种中间件。ORACLE数据库是目前世界上使用最为广泛的数据库管理系统,作为一个通用的数据库系统,它具有完整的数据管理功能;作为一个关系数据库,它是一个完备关系的产品;作为分布式数据库它实现了分布式处理功能。但它的所有知识,只要在一种机型上学习了ORACLE知识,便能在各种类型的机器上使用它[7]。4、网络通信协议简介 网络通信协议为连接不同操作系统和不同硬件体系结构的互联网络提供通信支持,是一种网络通用语言。网络通信的层次结构和网络通信的协议,是开发网络程序的基础。目前在网络编程方面最常用的是TCP/IP和UDP通信协议。通过这些协议,网络通信各主机可以用一种统一而非杂乱的规范,高效便捷地相互发送和接收消息。本系统在通讯功能实现中采用了TCP传输协议,直接使用的Java API提供的类Socket和Serversocket等来实现。 (1)TCP传输协议说明 TCP协议是面向连接的协议,比如说在客户端A和B进行连接之前必须首先建立数据通路,就向打电话一样,在通话之前必须先拨号,等待对方的接听以后才能进行通话。TCP协议中数据传输采取的是同步方式,当数据发送到对方时,必须等待接收方的应答信号后才能继续下一次的发送工作,即通常所讲的三次握手。由于TCP协议采用的是这种连接方式,因此由它建立的连接是可靠的。在网络不是十分理想的情况下,速度牺牲很大,但是却能够保证所传输的数据的正确性。(2)UDP传输协议说明 UDP协议采用的是面向无连接的通信方式,它在通信前不需要提前建立通信链路,它是异步的,数据的发送比较迅速,不需要等待应答信号。优点是发送速度较快,但是在数据的一致性方面不好,在网络差的情况下,容易丢失数据包。另外,使用UDP传输数据时对数据是有大小限制的,每个被传输的包必须限定在64KB之内[6]。 (3)Java Socket(套接字)说明 在Java语言里,使用Socket(套接字)模型来封装网络传输的具体动作。Java提供了Socket的相关包,Java中Socket的设计采用了面向对象的思路,模拟了TCP协议里客户端和服务器端的通信流程,并封装了创建连接、发送接收数据流、断开连接等方法。所以,使用Socket包,程序员不仅可以创建客户端和服务器之间的通信信道,还能实现发送和接收数据流等的网络通信功能[8]。 针对一个特定的连接和通信过程,服务器和客户端程序里都有一个Socket对象,我们可以想象一下其场景,在通信过程中,有一条虚拟的“光缆”构架在服务器和客户端之间,光缆的两头都插在了Socket这“插座”里。事实上,Java采用Socket包是对TCP协议的进一步抽象,更向程序员屏蔽了TCP通信的细节,具体表现在以下两方面 。一、在使用Socket类里的方法建立信道的时候,Socket类屏蔽了通过三次握手建立信道的全部流程,直接向程序员返回信道类的句柄(Socket类的实例)或是出错信息。 二、71 Socket类向程序员屏蔽了服务器和客户端之间的物理硬件指标和底层的连接方式,所以我们在使用Socket类开发网络程序时,可以简单地调用其提供的方法来传输数据,而不必关心数据流的传输和接收方式。5、C/S模式20世纪90年代出现并迅速占据主导地位的一种计算模式为客户机/服务器模式,简称为C/S模式,它实际上就是把主机—终端模式中原来全部集中在主机部分的任务一分为二,保留在主机上的部分负责集中处理和汇总运算,成为服务器;而下放到终端的部分负责为用户提供友好的交互界面,称为客户机。相对于以前的模式,C/S模式最大的改进是不再把所有软件都装进一台计算机,而是把应用系统分成两个不同的角色和两个不同的地位:一般在运算能力较强的计算机上安装服务器端程序,而在一般的PC上安装客户机程序。正是由于个人PC机的出现使客户机/服务器模式成为可能,因为PC机具有一定的运算能力,用它代替了上面第一种模式的哑终端后,就可以把主机端的一部分工作放在客户机端完成,从而减轻了主机的负担,也增加了系统对用户的响应速度和响应能力[9]。客户机和服务器之间通过相应的网络协议来进行通讯。客户机向服务器发出数据请求,服务器将数据传送给客户机进行计算,计算完毕,计算结果可返回给服务器。这种模式的优点充分利用了客户机的性能,使计算能力大大提高;另外,由于客户机和服务器之间的通讯是通过网络协议进行的,是一种逻辑的联系,因此物理上在客户机和服务器两端是易于扩充的。C/S模式是目前占主流的网络计算模式。71 第3章需求分析3.1系统基本功能描述客户端可以实现注册,登录,即时聊天,相互之间收发文件,发送截图,查看历史聊天记录等功能。收发消息时,可以实现离线接收。服务器端应当建立一个ServerSocket,并且不断进行侦听是否有客户端连接或者断开连接(包括判断没有响应的连接超时)。服务器端应当是一个信息发送中心,所有客户端的信息都传到服务器端,由服务器端根据要求分发信息。在后台管理系统,可以到对用户进行增删改查,查看在线用户,和踢用户下线。3.2系统需求分析聊天系统不外乎两个方面,服务器端和客户端。简单分析一下两个方面所要完成的任务,对设计这个程序来说,等于完成了一半。首先来看一下服务器端的任务:(1)服务器端应当建立一个ServerSocket,并且不断进行侦听是否有客户端连接或者断开连接(包括判断没有响应的连接超时)。 (2)服务器端应当是一个信息发送中心,所有客户端的信息都传到服务器端,由服务器端根据要求分发信息。以上就是服务器端最主要的两个任务。不难看出,服务器端的任务并不复杂。客户端应该完成的工作包括:(1)与服务器端建立通信通道,向服务器端发送信息。 (2)接收来自服务器的信息。相对服务器而言,客户端的任务更加简单,有了以上的简单分析,可以知道,解决上述四个问题,即完成了该聊天系统的核心。3.3数据流图数据流图(DFD),是从数据传递和加工角度,以图形方式来表达系统的逻辑功能、数据在系统内部的逻辑流向和逻辑变换过程。是结构化系统分析方法的主要表达工具及用于表示软件模型的一种图示方法 [10]。71 1.顶层数据流图图3-1系统顶层数据流图2.客户端数据流图图3-2客户端数据流图3.服务器端数据流图图3-3服务器端数据流图71 3.4数据字典数据字典的作用主要是对数据流程图中的数据项,数据结构,数据流,处理逻辑,数据存储和外部实体等方面进行具体的定义Error!Referencesourcenotfound.。建立数据字典的目的是为了保证全局数据的一致性和准确性。数据字典配以数据流程图就可以从图形和文字两方面对系统做出完整的定义和描述Error!Referencesourcenotfound.。1.离线消息表(1)数据项:MSG_ID含义说明:消息ID别名:消息ID类型:NUMBER(2)数据项:MSG_CONTENT含义说明:消息内容别名:消息内容类型:VARCHAR2长度:2000(3)数据项:MSG_SENDFROM含义说明:消息发送者别名:消息发送者类型:INTEGER(4)数据项:MSG_SENDTO含义说明:消息接收者别名:消息接收者类型:INTEGER(5)数据项:MSG_SENDTIME含义说明:消息发送时间别名:消息发送时间类型:DATE(6)数据项:MSG_REMARK含义说明:备注别名:备注类型:VARCHAR2长度:3000(7)数据项:MSG_TYPE含义说明:消息类型,如是群聊消息还是私聊消息别名:消息类型类型:VARCHAR2长度:271 2.用户信息表(1)数据项:U_ID含义说明:用户ID别名:用户ID类型:NUMBER(2)数据项:U_NAME含义说明:用户名别名:用户名类型:VARCHAR2长度:50(3)数据项:U_PWD含义说明:用户密码别名:用户密码类型:VARCHAR2长度:50(4)数据项:U_IP含义说明:IP地址别名:IP地址类型:VARCHAR2长度:50(5)数据项:U_STATE含义说明:用户状态别名:用户状态类型:VARCHAR2长度:50(6)数据项:U_GENDER含义说明:性别别名:性别类型:VARCHAR2长度:50(7)数据项:U_EMAIL含义说明:电子邮件别名:电子邮件类型:VARCHAR2长度:50(8)数据项:U_LAST_LOGIN含义说明:最后一次登录别名:最后一次登录71 类型:DATE(9)数据项:U_LAST_EXIT含义说明:最后一次退出别名:最后一次退出类型:DATE(10)数据项:U_REMARKE含义说明:备用别名:备用类型:VARCHAR2长度:3000(11)数据项:U_SIGNATURE含义说明:个性签名别名:个性签名类型:VARCHAR2长度:100(12)数据项:U_HEAD_IMG含义说明:用户头像别名:用户头像类型:VARCHAR2长度:100(13)数据项:U_TYPE含义说明:类型别名:类型类型:VARCHAR2长度:50(14)数据项:U_BIRTHDAY含义说明:用户生日别名:用户生日类型:DATE3.5用例图1.普通用户的用例图:71 图3-4普通用户用例图2.后台管理员的用例图:图3-5后台用户用例图71 第4章系统概要设计4.1系统总体流程图图4-1系统总体流程图71 4.2系统功能模块划分本系统主要分为注册、登录、聊天、后台管理四大模块。整个系统的详细结构如图4-2所示。图4-2系统总体功能模块划分各个功能模块设计如下:1、注册模块 在登录界面上有注册按钮,用户可以点击注册,填入个人相关资料,提交给服务器。服务器接收到信息后通过纯JDBC方式或者JDBC—ODBC桥接的方式连接数据库并添加记录。用户注册流程图如图4-3:图4-3用户注册流程图71 2、登录模块 用户在客户端输入账号和密码,然后建立与服务器端的连接,告诉服务器执行登录操作。服务器收到后,开始通过JDBC读取数据库,然后与用户输入的信息进行比对,如果成功,便打开主程序窗口。然后客户端向服务器请求读取好友列表,服务器收到该请求后从数据库中取出该用户的好友列表,然后向客户端发送这些信息,客户收到后就在主窗口显示好友。 用户登录流程图如图4-4:图4-4登录流程图3、实时聊天模块 客户端首先发送消息到服务器端,服务器端程序判断客户端发来的信息类型,如果是普通的聊天消息就根据发送者信息和接受者信息进行消息转发。例如客户端A向客户端B发送消息的处理过程如下:首先A向服务器发送消息,服务器程序判断消息类型,如果是普通的聊天消息,则解析该消息,得到该消息的发送者A,接受者B。接着判断B是否在线,如果在线就将消息发送过去,否则将消息存入数据库。B接收到A发来的信息,如果是未建立对话窗口,则在屏幕右下角出现弹窗提示。 此外还有群组聊天功能,可以在“官方聊天室”功能中实现一对多的聊天,即在聊天室发送的消息是面向所有在线用户的。用户聊天流程图如图4-5:71 图4-5聊天流程图4、系统后台管理模块 (1)系统服务:服务器端的管理员可以在这里启动后台的服务器,发布聊天室公告或者弹窗公告给所有在线用户。如果未开启服务器,则在客户端无法登录,并会返回相应的消息提示。 (2)用户管理:可以根据用户名或者用户ID查询已注册的用户详细信息,并且可以修改、保存相关信息。这是一个对数据库的简单的增删改查的操作。 71 第5章系统详细设计与实现5.1系统设计与实现本系统主要分为注册、登录、聊天、后台管理四大模块。 下面详细介绍各个模块的具体实现。5.1.1注册模块正如我们使用的QQ一样,使用之前我们要申请一个QQ号。本系统虽然没有设计这么复杂的流程,但是也必须在登录前注册账号。只有后台数据库里存在的用户才能使用本系统。注册界面如图5-1所示,填完消息点击注册即可。图5-1用户注册界面此外,信息填写不完整或填写有误将有错误提示。此处调用了JOptionPane对象的showMessageDialog方法,通过设置该方法的参数显示不同类型的提示框。邮箱地址的检测用到了Java里面的正则表达式相关知识,使用Pattern对象对邮箱地址格式的正则式进行编译,再调用Matcher对象的matches方法判断用户输入的邮箱是否与该格式匹配。71 注册完成后,通过JDBC技术连接MySQL数据库将记录插入数据库表中。 注册功能关键代码(注册成功窗口)代码如下:privateclassRegSuccessextendsJDialogimplementsActionListener{privateJTextAreatxtInfo=newJTextArea();privateJButtonbtnLogin=newJButton("直接登录");privateJButtonbtnReturn=newJButton("返回登陆界面");privateRegUseruser;publicRegSuccess(RegUseruser,Frameowner,booleanmodal){super(owner,modal);this.user=user;setSize(250,190);setResizable(false);Toolkittk=Toolkit.getDefaultToolkit();setLocation((tk.getScreenSize().width-getSize().width)/2,(tk.getScreenSize().height-getSize().height)/2);setTitle("注册信息");txtInfo.setText("恭喜!"+user.getRealname()+",注册成功! "+"用户昵称:"+user.getNickname()+" "+"登陆号码:"+user.getJqnum()+" "+"登陆密码:"+user.getPassword()+" "+"请妥善保管您的号码和密码!");txtInfo.setEditable(false);txtInfo.setOpaque(true);txtInfo.setBackground(this.getBackground());txtInfo.setPreferredSize(newDimension(200,100));txtInfo.setBorder(newTitledBorder(newLineBorder(Color.DARK_GRAY),"注册信息"));setLayout(newFlowLayout(FlowLayout.CENTER,10,10));btnLogin.addActionListener(this);btnReturn.addActionListener(this);add(txtInfo);add(btnLogin);add(btnReturn);setVisible(true);}publicvoidactionPerformed(ActionEvente){if(e.getSource()==btnLogin){dispose();71 RegisterPane.this.dispose();newMainPane(txtServerIP.getText(),Integer.parseInt(txtServerPort.getText()),user.getJqnum(),user.getPassword(),UserState.ONLINESTATE.getState());}if(e.getSource()==btnReturn){dispose();RegisterPane.this.dispose();newLoginPane();}}}网页上显示用户的注册账号信息,如图5-2:图5-2用户注册信息5.1.2登录模块登录模块用于验证客户端用户的合法性,用户输入用户名和密码后通过Msg对象将其封装成客户端消息,通过ObjectInputStream对象写入socket流中传给服务器,服务器收到客户端传来的Msg对象后解析出用户名和密码并和数据库的记录比对,两者完全正确方可成功登录。在登录界面(如图5-3)验证通过则会进入客户端好友列表界面(如图5-4),否则弹出一个MessageDialog提示用户名或密码错误。用户登录界面如图5-3所示:71 图5-3登录界面图客户端好友列表界面如图5-4所示:图5-4好友列表界面71 登录模块关键代码如下:publicvoidlogin(){Stringname=textField用户名.getText();Stringpassword=newString(pwd密码.getPassword());if(name.equals("")||password.equals(""))JOptionPane.showMessageDialog(this,"用户名和密码不能为空!","错误",JOptionPane.ERROR_MESSAGE);else{try{if(cs_TCP==null)cs_TCP=newCS_TCP(MyTools.QQServerIP,MyTools.QQServerPort,this,main);System.out.println("开始检测用户名和密码……");cs_TCP.sendMessage(Flag.LOGIN+MyTools.FLAGEND+name+MyTools.SPLIT1+password+MyTools.SPLIT1+main.getServerPort()+MyTools.SPLIT1+comboBox状态.getSelectedIndex());}catch(Exceptione){JOptionPane.showMessageDialog(null,"连接服务器失败!请检查网络连接或确保QQ服务器已启动!");}}}5.1.3聊天模块聊天模块是即时聊天系统的主要功能模块,本系统开发的目的就是实现即时聊天。在好友列表中单击鼠标选中一位好友后双击鼠标,即可打开聊天界面(如图5-5)。在界面下方的消息输入框内输入消息内容,点击发送按钮,即将消息发送给对方。点击表情按钮,还可以发送类似QQ表情的消息给对方。聊天界面如图5-5所示:71 图5-5聊天界面聊天模块关键代码如下:(1)鼠标事件,完成鼠标进入好友List中,选中好友,双击与好友进行聊天。privateclassListMouseAdapterextendsMouseAdapter{publicvoidmouseMoved(MouseEvente){//System.out.println(e.getSource());if(e.getSource()==listFriend){listFriend.clearSelection();intindex=listFriend.locationToIndex(e.getPoint());//System.out.println("index:"+index);listFriend.setSelectedIndex(index);}}publicvoidmouseClicked(MouseEvente){if(e.getSource()==listFriend){if(e.getClickCount()==2){71 chatWithFriend();}if(e.getButton()==MouseEvent.BUTTON3){popupMenu.show(listFriend,e.getX(),e.getY());}return;}if(e.getSource()==btnMenu){menu.show(btnMenu,e.getX()-25,e.getY()-75);}if(e.getSource()==btnSys){broadcastwindow.showNow();}}}(2)打开好友聊天窗口。privatevoidchatWithFriend(){Objectobj=listFriend.getSelectedValue();if(objinstanceofFriendUser){FriendUserfriendUser=(FriendUser)obj;intjqnum=friendUser.getJqnum();ChatPanechatPane=chat.get(jqnum);if(chatPane==null){chatPane=newChatPane(oos,friendUser,selfUser,true);chat.put(jqnum,chatPane);}elseif(chatPane.isDisplayable()){chatPane.setFocusable(true);chatPane.setState(NORMAL);}else{chatPane.setVisible(true);}}}packagedata;importjava.io.Serializable;importjava.util.Date;71 5.1.4后台管理模块作为用户我们只是使用了即时聊天系统的客户端功能,即我们电脑上安装的即时聊天软件。其实为了保证软件的正常运行,软件运行商在各地都有自己的代理服务器,以提供足够的带宽和计算能力。在软件的身后,自然会有强大的后台支撑,这保证了我们用户能够享受到即时聊天软件高质量的服务。本系统模拟了一个简单地后台管理的功能,主要提供了系统服务和用户管理两个功能。1.系统服务功能在系统服务里面,管理员可以启动和关闭服务器,实际上就是启动服务器端一些线程,开始监听来自客户端登录的请求,并随时做出相应的处理。同时查询数据库,返回用户信息。具体功能实现如图5-6所示:图5-6服务器端系统服务功能关键代码如下:/***启动服务器。*@throwsIOExceptionIO异常。71 */publicvoidstartServer()throwsIOException{isServiceRun=true;intport=Integer.parseInt(Server.prop.getProperty(GetParameter.keys[0]));table=newHashtable();server=newServerSocket(port);newThread(this).start();writeSysLog(DateDeal.getCurrentTime()+",JQ服务器服务启动成功!等待JQ用户上线...");}/***停止服务器。*@throwsIOExceptionIO异常。*/publicvoidstopServer()throwsIOException{isServiceRun=false;Enumerationen=table.elements();while(en.hasMoreElements()){ClientLinkclient=en.nextElement();client.updateUserState(client.jqnum,UserState.OFFLIENSTATE.getState());client.letClientQuit();}table.clear();table=null;if(server!=null)server.close();server=null;writeSysLog(DateDeal.getCurrentTime()+",JQ服务器服务停止成功!");}1.用户管理功能用户管理就是对系统注册用户信息的管理,可以查找、删除、修改相关内容,实质上就是通过JDBC对数据库的操作。这个面板中使用了JTable对象以实现对数据库表的加载显示。功能实现如图5-7所示:71 图5-7用户管理图关键代码如下:/***用户管理面板类。*/publicclassUserPaneextendsJPanelimplementsActionListener,Runnable{/**查询JQ用户*/privateJLabellblQuery=newJLabel("查询JQ用户");/**输入的查询的关键字*/privateJTextFieldtxtQuery=newJTextField("");/**查询的类型*/privateJComboBoxboxQuery=newJComboBox();/**查询*/privateJButtonbtnQuery=newJButton("查询");/**添加新用户*/privateJButtonbtnAddNew=newJButton("添加新用户");/**刷新重新获得所有用户*/71 privateJButtonbtnFlash=newJButton("刷新");/**显示用户的表格*/privateJTabletable=null;/**表格的模型*/privateDefaultTableModelmodel=null;/**状态栏*/privateJLabellblInfo=newJLabel("共有JQ用户:0");privateJPopupMenupopupMenu=newJPopupMenu();privateJMenuItemitemChange=newJMenuItem("修改");privateJMenuItemitemDelete=newJMenuItem("删除");publicUserPane(){init();btnAddNew.addActionListener(this);btnFlash.addActionListener(this);btnQuery.addActionListener(this);}5.1.5其他功能实现本系统除了以上四大主要功能之外,还具有其他一些功能。1.系统消息功能管理员可以在服务器端发送广播系统消息,在线用户均可在客户端接收到系统消息。具体实现如图5-8和5-9所示:图5-8发送广播系统消息71 图5-9用户接收系统消息2.查找及添加好友功能点击客户端好友列表下方“查找”按钮,即可进入查找功能界面(如图5-10)。然后通过设置查询条件来查找用户,点击查找后,系统会自动弹出查询的结果(如图5-11)。最后选中你想要添加的用户,点击加为好友按钮即可完成添加好友(如图5-12)。71 图5-10查找功能界面图5-11查找结果71 图5-12添加好友成功5.2数据库设计1、数据库需求分析  根据即时聊天系统的功能模块分析可知,一个最最简单的聊天系统至少应该包括一张用户基本档案的数据表。由于本系统功能设计理念较为简单,因此只包含了两张数据表:用户表(users)和消息表(msg)。用户表用于存储用户信息,消息表用于存储用户的离线聊天消息,因此本系统需要的数据源包括用户信息、离线聊天消息。2、概要设计 根据数据库的需求分析设计规划出的数据实体有:账户实体、用户信息实体、离线消息实体。每一个实体都是现实中实际存在的对象的抽象,并存在一定的数据关系。下面给出本系统的总体E-R图和数据库中各信息实体的E-R图。71 系统总体E-R模型图5-13系统总体E-R图用户的基本信息E-R模型:用户(用户ID,用户名,用户密码,用户IP地址,用户状态,用户性别,用户邮箱,用户最近一次登录日期,用户上一次退出日期,用户头像,用户生日)图5-14用户基本信息E-R图71 聊天消息的E-R模型:消息(消息ID,消息类型,消息内容,消息发送者,消息发送时间,消息接收者)图5-15聊天消息E-R图3、逻辑设计 本系统的数据库包含了两张表,分别为用户信息表、聊天消息表。下面简要介绍这两个表的设计。 (1)用户信息表: 该表中记录了本系统所有注册用户的用户名及其密码,以及其它一些个人信息。用户可以在客户端登录窗口通过输入用户名和匹配的密码登录,用户信息中只要有两者之一与该表内容不符便无法登录,系统会给出出错提示。 该表的设计如下:表5-1用户信息表字段名数据类型是否为主键U_IDNUMBER是U_NAMEVARCHAR2(50)否U_PWDVARCHAR2(50)否U_IPVARCHAR2(50)否U_STATEVARCHAR2(50)否U_GENDERVARCHAR2(50)否U_EMAILVARCHAR2(50)否U_LAST_LOGINDATE否U_LAST_EXITDATE否U_HEAD_IMGVARCHAR2(100)否U_BIRTHDAYDATE否71 (1)聊天消息表:记录了用户发送给离线好友的消息,管理员可以查看。包括发送者、接受者和消息产生的时间等。表5-2聊天消息表字段名数据类型是否为主键MSG_IDNUMBER是MSG_CONTENTVARCHAR2(2000)否MSG_SENDFROMINTEGER否MSG_SENDTOINTEGER否MSG_TYPEVARCHAR(2)否MSG_SENDTIMEDATE否4、物理设计 数据库最终要存储于存储设备上,将一个给定逻辑结构实施到具体的环境中时,逻辑数据模型要选取一个具体的工作环境,这个工作环境提供了数据存储结构与存取方法。(1)USERS表图5-16USERS表创建USERS表格createtableUSERS(u_idINTEGERnotnull,u_nameVARCHAR2(50)notnull,u_pwdVARCHAR2(50)notnull,u_ipVARCHAR2(50),u_stateVARCHAR2(50),u_genderVARCHAR2(50),71 u_emailVARCHAR2(50),u_last_loginDATE,u_last_exitDATE,u_remarkeVARCHAR2(3000),u_signatureVARCHAR2(100),u_head_imgVARCHAR2(100),u_typeVARCHAR2(50),u_birthdayDATE)tablespaceSYSTEMpctfree10pctused40initrans1maxtrans255storage(initial64Knext1Mminextents1maxextentsunlimited);--Create/Recreateprimary,uniqueandforeignkeyconstraintsaltertableUSERSaddconstraintPK_USERSprimarykey(U_ID)usingindextablespaceUSERSpctfree10initrans2maxtrans255storage(initial64Knext1Mminextents1maxextentsunlimited);(1)MSG表71 图5-17MSG表创建MSG表格createtableMSG(msg_idNUMBERnotnull,msg_contentVARCHAR2(2000)notnull,msg_sendfromINTEGERnotnull,msg_sendtoINTEGER,msg_sendtimeDATEnotnull,msg_remarkVARCHAR2(3000),msg_typeVARCHAR2(2))tablespaceUSERSpctfree10initrans1maxtrans255storage(initial64Knext1Mminextents1maxextentsunlimited);--AddcommentstothecolumnscommentoncolumnMSG.msg_idis'消息ID';commentoncolumnMSG.msg_contentis'消息内容';commentoncolumnMSG.msg_sendfromis'消息发送者';commentoncolumnMSG.msg_sendtois'消息接收者';71 commentoncolumnMSG.msg_sendtimeis'消息发送时间';commentoncolumnMSG.msg_remarkis'备用';commentoncolumnMSG.msg_typeis'消息类型,如是群聊消息还是私聊消息';--Create/Recreateindexescreateindex收发_FKonMSG(MSG_SENDFROM)tablespaceUSERSpctfree10initrans2maxtrans255storage(initial64Knext1Mminextents1maxextentsunlimited);--Create/Recreateprimary,uniqueandforeignkeyconstraintsaltertableMSGaddconstraintPK_MSGprimarykey(MSG_ID)usingindextablespaceUSERSpctfree10initrans2maxtrans255storage(initial64Knext1Mminextents1maxextentsunlimited);71 第6章软件测试与结果分析系统在开发的过程中,对于开发的各个时期都可能引入错误。所以,我们需要对开发的系统进行测试。所谓的软件测试就是,在一定的条件下操作程序,去发现程序当中存在的错误,以此来衡量软件的质量,并且对系统是否可以达到设计的要求近而进行评估的过程Error!Referencesourcenotfound.。虽然能够在各个阶段结束以前可以通过正式的技术评审和管理复审的方法去发现软件中的差错并去纠正,可是审核并不能够发现软件中所有的错误。软件测试成了对软件规格说明、软件设计和编码的最后也是最彻底的审核。通过软件测试,能够发现软件中绝大部分隐藏的错误,然后可以有效的提高软件产品功能的实现,产品的正确性、可靠性,进而可明显提高软件的质量Error!Referencesourcenotfound.。6.1软件测试软件测试基本包括以下几个方面:单元测试、集成测试、系统测试、验收测试、回归测试等。本次测试主要有以下几个测试的步骤:单元测试:对该程序的源代码进行测试,通过检查各个模块,查看每一个模块是否实现了之前规定的功能。集成测试:简单的说就是将各个模块组装起来进行的测试项目,主要是对相关软件体系的结构进行的测试。系统测试:就是将成形的该软件放到实际的运行环境里,与其他的系统组合然后进行的测试。其中包含一些功能测试,性能测试等。6.1.1白盒测试白盒测试,就是把软件当成一个透明的盒子,是对所有的逻辑路径进行的测试,然后查看是否实现设计的要求Error!Referencesourcenotfound.。大多的单元测试都使用白盒测试。白盒测试总体上分为静态和动态两大类。动态方法中最重要的就是路径和分支的测试。6.1.2黑盒测试黑盒测试,主要根据软件的需求分析书上所描述的功能,通过测试,观察是否实现所提到的功能,以及是否实现了需求分析书未提到的功能。该测试方法主要是按用户的角度出发的,进而来进行相应的测试。71 6.1.3系统测试系统测试是软件开发中一个重要的内容,在测试阶段可以发现项目的不足和错误之处,经过改正使系统更加完善。所以,系统测试是项目工程中必不可少的部分。6.2测试方法与总结6.2.1测试方法因为本系统主要是采用Java语言来进行编写的,在编写的程序中,系统是由很多具有不同功能的类组成的,在每个类编写完成后,需要编写一个main()方法,来测试其是否实现此功能。在测试中还可以使用MyEclipse的DeBug功能来设置程序的断点,跟踪程序这样也可以找到错误的原因,它的好处就是可以按照整个程序运行的顺序找到问题的原因。该测试主要以功能性测试为主,采用手动测试方法,在每个功能完成后可以通过编写测试用例来检测系统是否保证功能实现的正确性,是否有未完成或者与实现与需求不符合的功能。编写测试用例的方法主要有:等价类划分法、边界值设计、因果图、判定表方法、正交排列法和场景设计法等Error!Referencesourcenotfound.。下面是以用户登录模块来简单介绍一下测试。如图6-1、图6-2所示。123456图6-2登录模块流图NoYes输入用户名和密码登录是否正确登录开始结束登录成功图6-1登录模块流程图71 根据流图确定环形复杂性度量V(G),可以用三种方法求出V(G)的值:1.V(G)=边数-结点数+2=6-6+2=2。2.V(G)=2(个区域)。3.V(G)=谓词结点个数+1=1+1=2。根据路径设计相应的测试用例:路径1:测试步骤:输入正确的用户名和密码预期结果:用户成功登录。实际结果:登录成功。路径2:测试步骤1:输入错误的用户名或密码预期结果:输入错误,返回到输入用户名和密码实际结果:登录失败。测试步骤2:不输入用户名和密码预期结果:输入错误,返回到输入用户名和密码实际结果:登录失败。6.2.2测试总结该系统在测试过程中遇到了许多问题,像数据库的连接,各界面之间的转化不流畅,各个功能点的实现等。通过系统测试,逐步的解决了各种问题,使系统能够稳定的运行,达到了预期的效果。71 结论本次毕业设计的即时聊天系统,主要是以学习研究为目的,所有实现的功能都是最基本的。尽管这样,我还是做了很多准备工作,搜集了相关论文,参阅了相关书籍。由于系统界面设计较为繁杂,不像之前用Visual Studio可以拖控件,界面很快搞定,所以初期花费了不少时间去了解Java界面开发相关知识。这种搜集和学习相关知识的方法和经历对自己以后做课题研究有很大的启发意义。 在进行系统的分析与设计中我熟悉了从现状描述到系统建模以及系统实现的整个过程,这将自己以前在课堂上所学的基础知识及课外所学的知识串连起来,综合应用到一个真实的系统中去。编制系统开发计划使自己对分析设计的所有工作和进度有了清楚的了解。我深刻地认识到系统的可行性分析十分重要,这将决定系统的开发价值。如何实现服务器和客户端的通讯是本系统分析的重头,通过参考多位业界知名Java讲师的著作,我理解了如何用Java实现网络通信。然后将其转化为数据流程图,使自己理清了系统的工作思路,对于系统的流程有了清楚的把握。数据库的设计使自己学会了如何分析用户的需求,设计出合理规范的数据库。数据库设计是系统实施的一个基础,是整个系统后台的支撑。系统开发过程中我学习了使用MySQL进行数据库建表的相关知识,受益很多。 本系统采用免费开源的MyEclipse开发,由于时间有限,只开发了登录、注册、文字聊天、后台管理四个模块,通过动手编程使自己又重新回顾了Java语言的相关知识,熟悉了操作平台。在本系统开发的开发过程中我遇到了一些棘手问题,每遇到一个问题,我都想办法去解决,在这个过程中我充分利用了网络资源。有时在IT技术论坛CSDN论坛上发帖求助,也因此了解了一些论坛牛人,学到了不少知识。经过我的钻研,有的问题已经解决但还有一些期待实现。 成功解决的问题: 1、服务器端如何处理客户端的不同请求。客户端有时是请求登录验证,有时是请求返回好友列表,有时是请求发送文字消息给对方。开始的时候不知道怎么去做,然后查询了相关资料,参照别人的做法,设计了一个Message类,这个类不仅仅是字面意思消息,它是服务器客户端通信的实体,不管是聊天消息还是登录请求,任何服务器客户端的通信都封装成Message发送,接收方收到后根据Message对象的属性自行判断是何种消息,然后做相应处理。 2、离线消息推送。给不在线的人也应该能发送消息,但是对方如何接收到呢?这个问题我是这样解决的。凡是给不在线好友发送消息,统一写入数据库。每次客户端用户登录,首先执行一条线程,这条线程用来检测数据库msg表是否存在内容,有的话就按照发送方接收方推送给指定用户,然后删除数据库的离线消息。这个方法虽然笨了点,有冗余的操作,但是功能实现了。  期待解决的问题: 71 1、完成用户隐身登录不影响消息接收及记住密码自动登录的功能。 2、保存任何用户的聊天记录,并以加密的形式存储在数据库中。3、 如何将不同格式的文件发送给对方让我一筹莫展。 当然功能越想越多,有的是技术问题,有的是时间问题,总而言之期待以后完善。 本科毕业设计是对自己四年所学的一次综合性检验,虽然在做毕业设计的过程中遇到很多困难,但通过上网和查书解决了很多从未遇到过的问题,感觉很有成就感。这次的毕业设计确实让我学到了很多知识。最大的感概就是系统开发之前的设计是尤为重要的,这决定了系统开发的工程量、效率。设计能力才是检验一个软件工程师水平的指标。站在软件开发技术金字塔顶端的往往是那些资深的系统架构师,这应当成为我的奋斗目标!大学里学的课程如数据结构与算法、计算机组成原理、操作系统等课程正是为我们走向“金字塔”铺路的,只有基本功扎实才能在IT技术领域游刃有余。71 致谢历时半载,从论文选题到搜集资料,从完成开题报告到写初稿,再经过反复修改,直至最终成型,这期间经历了喜悦、聒噪、痛苦和彷徨,在写作论文的过程中心情是如此复杂。如今,伴随着这篇毕业论文的最终成稿,复杂的心情烟消云散,自己甚至还有一点成就感。对于本篇毕业论文的写作,我得到了很多老师和同学的帮助,其中我的论文指导老师范忠诚老师对我的指导和帮助尤为重要。在我做毕业设计的每个阶段,从选题到查阅资料,再到论文提纲的确定,中期论文的修改,后期论文格式调整等各个环节中,范老师都给予了我悉心的指导。在这几个月的相处中,范老师给予我的不仅仅是在论文写作方面的帮助,他广博的学识、深厚的学术素养、严谨的治学精神和一丝不苟的工作作风也给我留下了深刻的印象,让我受益终生。在此谨向范忠诚老师致以诚挚的谢意和崇高的敬意。同时,本篇毕业论文的写作也得到了李杭、张阿飞等同学的热情帮助,感谢在整个毕业设计期间给予我帮助的同学,以及曾经在各个方面给予过我帮助的伙伴们,是他们弥补了我在部分方面知识的匮乏,从而加快了本篇论文的进展,帮助我如期完成自己的毕业论文。伴随着本片论文的落稿,大学四年学习时光也已经接近尾声,在此我想对我的母校、我的老师、我的同学以及我的父母和亲人们表达我由衷的谢意。71 参考文献[1]印旻,王行言.Java语言与面向对象程序设计(第二版)[M].北京:清华大学出版社,2007.11 .[2](美)马劳克林.深入浅出Ajax(中文版)[M].南京:南京大学出版社,2008.[3]李刚.轻量级JavaEE企业应用实战——Struts2+Spring+Hibernate整合开发[M].北京:电子工业出版社,2008.[4]熊晓敏,陈惠清.基于Java的网络即时通讯系统的设计与实现[J].计算机与现代化,2005.12.[5]罗军舟,黄健.TCP/IP协议及网络编程技术[M].北京:清华大学出版社,2005.8.[6](美)鲍格斯坦(Bergsten,H.)著,林琪,朱涛江译.JSP设计(第三版)ReillyJava系列[M].北京:中国电力出版社,2004.[7]王国辉,王易.JSP数据库系统开发案例精选[M].北京:人民邮电出版社,2006.[8]孙卫琴.Java网络编程精解[M].北京:电子工业出版社,2007.03.[9]张虹.软件工程与软件开发工具[M].北京:清华大学出版社,2004.1.[10]BrueeEekel.ThinkingInJava(第三版)[M].北京:机械工业出版社,2005.2.[11]DavidGallardo.SpringinAction[J].ACMcomputingsurveys,2005.[12]ThomasM.Connolly,CarolynE.Eegg著,何玉洁,黄婷儿译.数据库设计教程第2版[M].北京:机械工业出版社,2005.[13](美)Roger S.Pressman 著,郑人杰,马素霞 等译.软件工程:实践者的研究方法[M].北京:机械工业出版社,2011.08. [14]钱乐秋,朱军钰.软件工程[M].北京:清华大学出版社,2006.[15]宫学生,丁男.移动通信软件框架的设计与实现[J].计算机系统应用,2010.05.71 附录附录1:系统的配置与使用1.1硬件条件由于系统主要定位于内部局域网,计算机配置需求不是很高,如下:即时通信服务器:50用户规模双CPU:PIV2.4GMHZ以上,内存:1G以上。客户端:CPUPIII2.0以上,内存:256M以上。1.2软件条件即时通信服务器:Windows2003。客户端:操作系统Win98、Win2000、Win2003、WinXP。附录2:JDK安装及使用选择好安装路径。安装到计算机上。下来进行一些设置。首先右键点我的电脑。打开属性。然后选择“高级”里面的“环境变量”,在新的打开界面中的系统变量需要设置三个属性“java_home”、“path”、“classpath”,其中在没安装过jdk的环境下。path属性是本来存在的。而java_home和classpath是不存在的。首先点“新建”,然后在变量名写上java_home,顾名其意该变量的含义就是java的安装路径,呵呵,然后在变量值写入刚才安装的路径“C:jdk1.6”;其次在系统变量里面找到path,然后点编辑,path变量的含义就是系统在任何路径下都可以识别java命令,则变量值为“%java_home%bin;%java_home%jrebin”,(其中“%java_home%”的意思为刚才设置java_home的值),也可以直接写上“C:jdk1.6bin”;最后再点“新建”,然后在变量名上写classpath,该变量的含义是为java加载类(classorlib)路径,只有类在classpath中,java命令才能识别。其值为“.;%java_home%lib;%java_home%libtools.jar(要加.表示当前路径)”,与相同“%java_home%有相同意思”。以上三个变量设置完毕,则按“确定”直至属性窗口消失,下来是验证看看安装是否成功。先打开“开始”->“运行”,打入“cmd”,进入dos系统界面。然后打“java-version”,如果安装成功。系统会显示javaversionjdk"1.6.0"。确保安装在C盘文件名为jdk1.6,环境变量直接复制就可以了。附录3:服务器端安装及使用首先,将系统存放到C:CHAT目录下;然后,在安装完JDK后,对系统进行配置,注要是将path路径制定到chat中的存储路径;最后:“开始”->“运行”,打入“cmd”,进入dos系统界面。然后输入cd71 c:chatsrcorgselerserviceAppServer.java。附录4:使用手册4.1服务器端安装服务器,并运行服务器;4.2客户端安装客户端,并运行客户端;用户注册:其中要求输入用户昵称,性别,年龄,用户密码以及邮箱,其中,昵称必须唯一值。用户登录:打开客户端,输入用户名和密码,点击“登录”;用户聊天:在“聊天内容”对应的文本框中,输入聊天信息,在“你对”聊天对象下拉菜单中选择聊天对象,最后点击“发送”按钮;信息查看:在“聊天信息”文本框中,查看聊天信息。保存聊天记录:点击“保存”,则将聊天信息保存在客户端中;用户退出:点击“退出”。附录5:程序源代码(1)JQ客户端主程序类。packageclient;importjava.awt.Font;importjava.awt.FontFormatException;importjava.io.BufferedInputStream;importjava.io.File;importjava.io.IOException;importtools.SetFont;importclient.frm.LoginPane;publicclassJQClient{/***JQ客户端主程序类。
*加载字体到UIManager,启动登陆窗口。*/publicstaticvoidmain(String[]args){try{Fontfont=Font.createFont(Font.TRUETYPE_FONT,newBufferedInputStream(JQClient.class.getResourceAsStream("/tools/simsun.ttc")));font=font.deriveFont(Font.PLAIN,12);SetFont.setFont(font);}catch(FontFormatExceptione){71 System.out.println("错误:"+e.getMessage());}catch(IOExceptione){System.out.println("错误:"+e.getMessage());}newLoginPane();}}(2)登录面板类packageclient.frm;publicclassLoginPaneextendsJFrameimplementsActionListener{privateJLabellblImg=newJLabel();privateJLabellblJQNum=newJLabel("JQ账号");privateJComboBoxboxJQNum=newJComboBox();privateJLabellblPassword=newJLabel("JQ密码");privateJPasswordFieldpfPassword=newJPasswordField();privateJLabellblState=newJLabel("状态:");privateJComboBoxboxState=newJComboBox();privateJCheckBoxboxAutoLogin=newJCheckBox("自动登录");privateJButtonbtnRegister=newJButton("申请账号");privateJButtonbtnSet=newJButton("设置↓");privateJButtonbtnLogin=newJButton("登录");privateJLabellblServerIP=newJLabel("服务器IP:");privateJTextFieldtxtServerIP=newJTextField("127.0.0.1");privateJLabellblServerPort=newJLabel("端口:");privateJTextFieldtxtServerPort=newJTextField("3608");prjavax.swing.JButton;publicLoginPane(){setTitle("JQ用户登录");setSize(324,235);setResizable(false);Toolkittk=Toolkit.getDefaultToolkit();setLocation((tk.getScreenSize().width-getSize().width)/2,(tk.getScreenSize().height-getSize().height)/2);setBackground(newColor(224,244,251));init();btnLogin.addActionListener(this);btnRegister.addActionListener(this);btnSet.addActionListener(this);71 setDefaultCloseOperation(EXIT_ON_CLOSE);setVisible(true);}privatevoidinit(){lblImg.setIcon(newImageIcon(LoginPane.class.getResource("/client/images/top.gif")));lblImg.setPreferredSize(newDimension(325,47));boxState.addItem(UserState.ONLINESTATE);boxState.addItem(UserState.HIDDENSTATE);boxState.addItem(UserState.DEPARTURESTATE);boxState.addItem(UserState.BUSYSTATE);boxState.setBackground(newColor(240,250,255));boxState.setPreferredSize(newDimension(60,20));boxAutoLogin.setBackground(newColor(240,250,255));boxJQNum.setEditable(true);boxJQNum.setPreferredSize(newDimension(140,20));pfPassword.setPreferredSize(newDimension(140,20));txtServerIP.setPreferredSize(newDimension(80,20));txtServerPort.setPreferredSize(newDimension(50,20));JPanelpane=newJPanel();pane.setBackground(newColor(240,250,255));pane.setBorder(newLineBorder(newColor(144,185,215)));pane.setLayout(newFlowLayout(FlowLayout.CENTER,15,12));pane.setPreferredSize(newDimension(300,110));pane.add(newFillWidth(20,20,newColor(240,250,255)));pane.add(lblJQNum);pane.add(boxJQNum);pane.add(newFillWidth(20,20,newColor(240,250,255)));pane.add(newFillWidth(20,20,newColor(240,250,255)));pane.add(lblPassword);pane.add(pfPassword);pane.add(newFillWidth(20,20,newColor(240,250,255)));pane.add(lblState);pane.add(boxState);pane.add(boxAutoLogin);TitledBordertb=newTitledBorder(newLineBorder(Color.GRAY),"网络设置");JPanelpaneSet=newJPanel();71 paneSet.setPreferredSize(newDimension(300,60));paneSet.setBorder(tb);paneSet.add(lblServerIP);paneSet.add(txtServerIP);paneSet.add(newFillWidth(30,20));paneSet.add(lblServerPort);paneSet.add(txtServerPort);setLayout(newFlowLayout(FlowLayout.CENTER,5,0));add(lblImg);add(newFillWidth(100,8));add(pane);add(newFillWidth(300,8));add(btnRegister);add(btnSet);add(newFillWidth(65,20));add(btnLogin);add(newFillWidth(300,8));add(paneSet);}/***设置按钮、登陆按钮、注册按钮的事件。*/publicvoidactionPerformed(ActionEvente){if(e.getSource()==btnSet){if(isSet){isSet=false;setSize(getWidth(),getHeight()-65);btnSet.setText("设置↓");}else{isSet=true;setSize(getWidth(),getHeight()+65);btnSet.setText("设置↑");}}if(e.getSource()==btnLogin){dispose();new71 MainPane(txtServerIP.getText(),Integer.parseInt(txtServerPort.getText()),Integer.parseInt(boxJQNum.getSelectedItem().toString()),newString(pfPassword.getPassword()),((UserState)boxState.getSelectedItem()).getState());}if(e.getSource()==btnRegister){dispose();newRegisterPane();}}}(3)主程序类、JQ的主框架类。publicclassMainPaneextendsJFrameimplementsActionListener{privateJLabellblPhoto=newJLabel();privateJComboBoxboxState=newJComboBox();privateJLabellblNickName=newJLabel();privateJTextAreatxtSignature=newJTextArea();privateJListlistFriend;//=newJList();privateDefaultListModellistModel=null;privateJButtonbtnMenu=newJButton("菜单");privateJButtonbtnFind=newJButton("查找");privateJButtonbtnSys=newJButton("系统消息");privateJLabellblLoginBar=newJLabel();privateJButtonbtnCancleLogin=newJButton("取消登录");privateJPanelfillWidth=newFillWidth(118,120,Color.WHITE);privateSocketclient=null;privateObjectOutputStreamoos=null;privateObjectInputStreamois=null;privateHashMapchat=null;privateFriendUserselfUser=null;privateStringserverIp;privateIntegerserverPort;privateIntegerjqnum;privateStringpassword;privateIntegerstate;privateJPopupMenupopupMenu=null;privateJMenuItemitemChat=null;privateJMenuItemitemDelete=null;privateJMenuItemitemFriendInfo=null;privateJMenuItemitemLog=null;71 privateFindWindowfindWindow=null;privateJPopupMenumenu=newJPopupMenu();privateJMenuItemitemQuit=newJMenuItem("退出");privateBroadcastwindowbroadcastwindow=null;privateThreadthread=null;/***登陆后显示的主面板的构造函数。*@paramserverIp服务器ip。*@paramserverPort服务器端口。*@paramjqnum登陆的jq号码。*@parampassword登陆的jq密码。*@paramstate登陆的状态。*/publicMainPane(StringserverIp,IntegerserverPort,Integerjqnum,Stringpassword,Integerstate){this.serverIp=serverIp;this.serverPort=serverPort;this.jqnum=jqnum;this.password=password;this.state=state;//System.out.println(jqnum+":"+password+"State:"+state);setTitle("JQ2016");setSize(200,550);setResizable(false);Toolkittk=Toolkit.getDefaultToolkit();setLocation((tk.getScreenSize().width-getSize().width)-10,(tk.getScreenSize().height-getSize().height)/2-30);//init();getContentPane().setBackground(Color.WHITE);initLoginPane();//setDefaultCloseOperation(EXIT_ON_CLOSE);setVisible(true);thread=newLoginThread();thread.start();}/***初始化用户按下登陆按钮后,主面板显示登陆进度条窗体。*/71 privatevoidinitLoginPane(){btnCancleLogin.setPreferredSize(newDimension(60,20));btnCancleLogin.setMargin(newInsets(0,0,0,0));btnCancleLogin.setFocusPainted(false);lblLoginBar.setIcon(newImageIcon(MainPane.class.getResource("/client/images/loginbar.gif")));setLayout(newFlowLayout(FlowLayout.CENTER,20,10));add(fillWidth);add(lblLoginBar);//add(newFillWidth(1,2,Color.WHITE));add(btnCancleLogin);btnCancleLogin.addActionListener(this);//initMain();}/***初始化用户登陆成功后,显示主窗体。*@paramv好友列表。*/privatevoidinitMain(Vectorv){newMSG(25);selfUser=v.get(0);v.remove(0);setTitle("JQ2016"+selfUser.getJqnum());popupMenu=newJPopupMenu();itemChat=newJMenuItem("发送即时消息");itemDelete=newJMenuItem("删除该好友");itemFriendInfo=newJMenuItem("查看好友资料");itemLog=newJMenuItem("聊天记录");popupMenu.add(itemChat);popupMenu.add(itemFriendInfo);popupMenu.addSeparator();popupMenu.add(itemLog);popupMenu.addSeparator();popupMenu.add(itemDelete);menu.add(newJMenuItem("设置"));menu.addSeparator();menu.add(newJMenuItem("帮助"));71 menu.addSeparator();menu.add(itemQuit);itemQuit.addActionListener(this);btnMenu.addMouseListener(newListMouseAdapter());itemChat.addActionListener(this);itemDelete.addActionListener(this);itemFriendInfo.addActionListener(this);itemLog.addActionListener(this);btnMenu.setMargin(newInsets(0,5,0,5));btnFind.setMargin(newInsets(0,5,0,5));btnFind.addActionListener(this);btnSys.setMargin(newInsets(0,5,0,5));btnSys.addMouseListener(newListMouseAdapter());lblPhoto.setSize(50,50);lblPhoto.setLocation(5,5);lblPhoto.setOpaque(true);lblPhoto.setBackground(newColor(116,220,253,150));lblPhoto.setHorizontalAlignment(SwingConstants.CENTER);lblPhoto.setIcon(newPortrait(selfUser.getPhoto(),selfUser.getState()));lblPhoto.setBorder(newLineBorder(newColor(60,168,206),1,true))boxState.setSize(50,20);boxState.setLocation(60,5);boxState.addItem(UserState.ONLINESTATE);boxState.addItem(UserState.HIDDENSTATE);boxState.addItem(UserState.DEPARTURESTATE);boxState.addItem(UserState.BUSYSTATE);boxState.setSelectedIndex(selfUser.getState());lblNickName.setSize(80,20);lblNickName.setLocation(115,5);lblNickName.setText(selfUser.getNickName()+"["+UserState.getStateName(selfUser.getState())+"]");txtSignature.setText(selfUser.getSignature());txtSignature.setEditable(false);txtSignature.setLineWrap(true);txtSignature.setBackground(getBackground());JScrollPanespSign=newJScrollPane(txtSignature);spSign.setSize(125,25);71 spSign.setLocation(60,30);spSign.setBorder(newEmptyBorder(newInsets(0,0,0,0)));JPanelpaneTop=newJPanel();paneTop.setLayout(null);paneTop.setPreferredSize(newDimension(200,60));paneTop.add(lblPhoto);paneTop.add(boxState);paneTop.add(lblNickName);paneTop.add(spSign);listModel=newDefaultListModel();for(FriendUseruser:v){listModel.addElement(user);}setLayout(newBorderLayout());add(paneTop,BorderLayout.NORTH);add(sp,BorderLayout.CENTER);add(newFillWidth(5,5),BorderLayout.EAST);add(newFillWidth(5,5),BorderLayout.WEST);add(paneBottom,BorderLayout.SOUTH);setVisible(true);broadcastwindow=newBroadcastwindow();}/***取消按钮、聊天按钮、删除好友、好友按钮、查找按钮事件。*/publicvoidactionPerformed(ActionEvente){if(e.getSource()==btnCancleLogin){closeClient();System.exit(0);return;}if(e.getSource()==itemChat){chatWithFriend();return;}if(e.getSource()==itemDelete){JOptionPane.showMessageDialog(null,"功能制作中...");return;71 }if(e.getSource()==itemFriendInfo){JOptionPane.showMessageDialog(null,"功能制作中...");return;}if(e.getSource()==itemLog){JOptionPane.showMessageDialog(null,"功能制作中...");return;}if(e.getSource()==btnFind){if(findWindow==null)findWindow=newFindWindow(this,false);else{findWindow.setVisible(true);}return;}if(e.getSource()==itemQuit){quit();closeClient();System.exit(0);}}/***根据好友号码获得listFriendUser中的好友。*@paramjqnum好友的jq号码。*@return好友的信息FriendUser类。不存在是返回空。*/privateFriendUsergetFriendUserFromList(intjqnum){for(inti=0;i"+user.getNickName()+"["+user.getJqnum()+"]"+"
"+user.getSignature()+"");}returnretValue;}}/***鼠标事件,完成鼠标进入好友List中,选中好友,双击与好友进行聊天等。*/privateclassListMouseAdapterextendsMouseAdapter{publicvoidmouseMoved(MouseEvente){//System.out.println(e.getSource());if(e.getSource()==listFriend){listFriend.clearSelection();intindex=listFriend.locationToIndex(e.getPoint());//System.out.println("index:"+index);listFriend.setSelectedIndex(index);}}publicvoidmouseClicked(MouseEvente){if(e.getSource()==listFriend){71 if(e.getClickCount()==2){chatWithFriend();}if(e.getButton()==MouseEvent.BUTTON3){popupMenu.show(listFriend,e.getX(),e.getY());}return;}if(e.getSource()==btnMenu){menu.show(btnMenu,e.getX()-25,e.getY()-75);}if(e.getSource()==btnSys){broadcastwindow.showNow();}}}/***打开好友聊天窗口。*/privatevoidchatWithFriend(){Objectobj=listFriend.getSelectedValue();if(objinstanceofFriendUser){FriendUserfriendUser=(FriendUser)obj;intjqnum=friendUser.getJqnum();ChatPanechatPane=chat.get(jqnum);if(chatPane==null){chatPane=newChatPane(oos,friendUser,selfUser,true);chat.put(jqnum,chatPane);}elseif(chatPane.isDisplayable()){chatPane.setFocusable(true);chatPane.setState(NORMAL);}else{chatPane.setVisible(true);}}}71 /***登陆线程。处理服务端的信息以及发送消息到服务端。*/privateclassLoginThreadextendsThread{publicLoginThread(){try{client=newSocket(serverIp,serverPort);MainPane.this.addWindowListener(newMyWindowAdapter());oos=newObjectOutputStream(newBufferedOutputStream(client.getOutputStream()));LoginUserloginUser=newLoginUser();loginUser.setJqnum(jqnum);loginUser.setPassword(password);loginUser.setState(state);JQMessagemessage=newJQMessage();message.setType(20);message.setObj(loginUser);newWriteThread(message).start();ois=newObjectInputStream(newBufferedInputStream(client.getInputStream()));//oos=newObjectOutputStream(client.getOutputStream());//ois=newObjectInputStream(client.getInputStream());}catch(UnknownHostExceptione){closeClient();JOptionPane.showMessageDialog(null,"请确保输入的服务器IP和端口正确!"+e.getMessage());dispose();newLoginPane();}catch(IOExceptione){closeClient();JOptionPane.showMessageDialog(null,"请确保输入的服务器IP和端口正确!"+e.getMessage());dispose();newLoginPane();}}publicvoidrun(){try{71 JQMessagemessage=null;while(ois!=null){Objectobj=ois.readObject();if(objinstanceofJQMessage){message=(JQMessage)obj;inttype=message.getType();switch(type){case21://登陆成功if(message.getObj()instanceofVector){Vectorv=(Vector)message.getObj();initMain(v);}break;case22://登录失败closeClient();JOptionPane.showMessageDialog(null,message.getObj().toString());dispose();newLoginPane();break;case23://账号在别处登录causeLetClientQuit(message);break;case25://好友上线dealFriendUserLogin(message);break;case31://接收到消息dealRecord(message.getObj(),type);break;case41://接受当前在线用户数dealOnlineNum(message.getObj());break;case43://接受在线的用户显示到table上dealShowOnlineUser(message.getObj());break;case45:JOptionPane.showMessageDialog(null,message.getObj().toString());71 break;case46:JOptionPane.showMessageDialog(null,message.getObj().toString());break;case90://服务端退出causeLetClientQuit(message);break;case91:dealBroadcast(message);break;}}}}catch(IOExceptione){System.out.println("发生异常:"+e.getMessage());closeClient();JOptionPane.showMessageDialog(null,"和服务端连接发生错误:"+e.getMessage()+",请重新登录!");System.exit(0);}catch(ClassNotFoundExceptione){System.out.println("发生异常:"+e.getMessage());closeClient();JOptionPane.showMessageDialog(null,"和服务端连接发生错误:"+e.getMessage()+",请重新登录!");System.exit(0);}}}/***处理广播。*@parammessageJQMessage消息对象。*/privatevoiddealBroadcast(JQMessagemessage){newMSG(message.getType());if(broadcastwindow!=null){broadcastwindow.txt.setText(message.getObj().toString());broadcastwindow.showNow();71 }}/***有消息来时出发声音。*@paramtype消息的类型。*/privatevoidnewMSG(inttype){//播放*.au文件时建议使用下面的方法//AudioClipaudioClip=null;//if(n==31)//audioClip=Applet.newAudioClip(MainPane.class.getResource("../sound/msg.au"));//if(n==91)//audioClip=Applet.newAudioClip(MainPane.class.getResource("../sound/system.au"));//audioClip.play();//播放*.wav文件时建议使用下面的方法try{AudioStreamaudioStream=null;switch(type){case25:audioStream=newAudioStream(getClass().getResourceAsStream("/client/sound/global.wav"));break;case31:audioStream=newAudioStream(getClass().getResourceAsStream("/client/sound/msg.wav"));break;case91:audioStream=newAudioStream(getClass().getResourceAsStream("/client/sound/system.wav"));break;default:audioStream=newAudioStream(getClass().getResourceAsStream("/client/sound/msg.wav"));break;}AudioPlayer.player.start(audioStream);71 }catch(IOExceptione){System.out.println("在播放声音文件时[type="+type+"],发生异常:"+e.getMessage());}}/***处理好友上线时消息。*@parammessage*/privatevoiddealFriendUserLogin(JQMessagemessage){Objectobj=message.getObj();if(objinstanceofFriendUser){newMSG(message.getType());FriendUserfriendUser=(FriendUser)obj;if(listModel.contains(friendUser)){for(inti=0;i

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
关闭