基于java的QQ聊天系统毕业设计说明书.docx
《基于java的QQ聊天系统毕业设计说明书.docx》由会员分享,可在线阅读,更多相关《基于java的QQ聊天系统毕业设计说明书.docx(66页珍藏版)》请在冰点文库上搜索。
基于java的QQ聊天系统毕业设计说明书
基于java的QQ聊天系统
第一章.绪论
1.1课题背景
随着互联网逐步普及,人们的生活和工作也越来越离不开信息网络的支持,而聊天室是人们最常见,最直接的网上交流的方式。
本聊天系统以聊天交流为主,为广大用户提供一个借助网络进行人际交往的平台,也是网络与现实最贴近的实用型网站。
本文所介绍的网络聊天系统是基于开放的JAVA应用程序开发设计的,其主要特性是能动态、实时的完成信息的传递,且具有高效的交互性,更有效的处理客户请求,易于维护和更新,其运行所需环境及其工作流程和各个功能控件的工作原理将在本文依次介绍,并且文中提供了部分程序源代码。
1.2课题研究的目的和意义
即时通讯系统的最大特点是在网上进行信息的实时交流。
即时通讯系统的发展使得人们可以进行网上社交,获得社会的尊重,实现自我需求,这同时也为了网络即时通讯软件发展的驱动力。
而物质文明的日益发达所带来的副作用,有使得人们习惯与周围的人保持距离。
以致人们更愿意对陌生人敞开心扉。
与传统通讯方式相比,即时通讯系统具有快捷,廉价,隐秘性高的特点,在网络中可以跨年龄,身份,行业,地域的限制,达到人与人,人与信息之间的零交流。
从这点上讲,网络即时通讯的出现改变人们的沟通方式和交友文化,大大拓展了个人生活交流的空间。
1.3国内外概况
目前国内外做聊天系统的很多,产品也是琳琅满目,国内有诸如腾讯QQ与新浪UC网易泡泡等,国外著名的有MSN以及跨平台GAIM等.本人取最具有代表性的QQ和MSN进行了一些研究,为我毕业设计聊天系统做了充分的准备.
腾讯无疑使国内即时通讯市场的霸主,自从99年进入即时通讯领域并迅速占领市场之后,其在国内用户数量始终高居榜首,即时近几年面对微软MSN的强大攻势,腾讯QQ的市场占有率依然稳步增长.参考了许多资料,以及自己通过观察腾讯QQ运行时的各种细节.可以确定腾讯QQ是以多服务器提供服务,服务器总控客户端客户端之间UDP直连通信的.并且在两个客户端之间不能建立直接的情况下,才由服务器进行中转通信.
第2章.系统设计方案的研究
2.1系统的设计方案
聊天系统的设计跟普通网站设计有着许多不同的地方,普通网站设计所考虑的因素,例如,普通网站需要对布局进入大量美化以及动画设计等等,而聊天室只要提供满足访客双方直接实时聊天即可。
因此,在设计聊天系统的过程中,必须要考虑好以下几个设计要点:
1、实现思想
在Internet上的聊天程序一般都是以服务器提供服务端连接响应,使用者通过客户端程序登录到服务器,就可以与登录在同一服务器上的用户交谈,这是一个面向连接的通信过程。
因此,程序要在TCP/IP环境下,实现服务器端和客户端两部分程序。
2、服务器端工作流程
服务器端通过socket()系统调用创建一个Socket数组后(即设定了接受连接客户的最大数目),与指定的本地端口绑定bind(),就可以在端口进行侦听listen()。
如果有客户端连接请求,则在数组中选择一个空Socket,将客户端地址赋给这个Socket。
然后登录成功的客户就可以在服务器上聊天了。
3、客户端工作流程
客户端程序相对简单,只需要建立一个Socket与服务器端连接,成功后通过这个Socket来发送和接收数据就可以了。
系统采用客户/服务器摸式(如图)
2.2设计方案的分析
聊天系统不外乎两个方面,服务器端和客户端。
简单分析一下两个方面所要完成的任务,对设计这个程序来说,等于完成了一半。
首先来看一下服务器端的任务:
1.服务器端应当建立一个ServerSocket,并且不断进行侦听是否有客户端连接或者断开连接(包括判断没有响应的连接超时)。
2.服务器端应当是一个信息发送中心,所有客户端的信息都传到服务器端,由服务器端根据要求分发信息。
以上就是服务器端最主要的两个任务。
不难看出,服务器端的任务并不复杂。
客户端应该完成的工作包括:
1.与服务器端建立通信通道,向服务器端发送信息。
2.接收来自服务器的信息。
相对服务器而言,客户端的任务更加简单,有了以上的简单分析,可以知道,解决上述四个问题,即完成了该聊天系统的核心。
2.3采用的关键技术
系统采用的关键技术有:
2.3.1Socket网络通信技术
Java具有强大地网络编程功能,它提供了基于Socket的通信方式(Socket—base—communication),使得应用程序可以像读文件一样从Socket读取数据和写入数据,java提供了流Socket和数据包Socket。
两者分别基于传输控制协议和用户数据报协议。
所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。
应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
它的基本结构是:
建立套接字,绑定地址和端口,建立套接口和队列,接受连接,处理连接,关闭套接字。
对应用程序,它的基本结构是:
建立套接字,连接服务器,处理连接,关闭套接字。
Socket在应用程序中创建,通过一种绑定机制和驱动程序建立连接,告诉自己对应的ip和port。
此后,应用程序送给socket数据,有socket交给驱动程序向网络上发送出去,计算机从网络上收到与该socket绑定的IP+PORT相关的数据后,由驱动程序交给Socket,应用程序片可以从中提取数据。
数据发送过程:
数据接收过程:
2.3.2UDP协议
UDP是UserDatagramProtocol的简称,中文名是用户数据包协议,是OSI参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。
它是IETFRFC768是UDP的正式规范。
虽然UDP协议不可靠,但是也不会轻易导致传输失效。
UDP连接框架如图:
UDP协议传输效率较高,与他相比,TCP协议传输效率较低,TCP是面向连接的传输控制协议,而UDP提供了无连接的数据报服务;TCP具有高可靠性,确保传输数据的正确性,不出现丢失或乱序;UDP在传输数据前不建立连接,不对数据报进行检查与修改,无须等待对方的应答,所以会出现分组丢失、重复、乱序,应用程序需要负责传输可靠性方面的所有工作;也正因为以上特征,UDP具有较好的实时性,工作效率较TCP协议高;UDP段结构比TCP的段结构简单,因此网络开销也小。
UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。
由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。
2.3.3并发服务器技术
并发服务器原理及技术支持并发服务器是指在服务器具有良好的安全性和稳定性的前提下,接收客户端的请求后,立即用一个新的线程来实现服务器与该客户进行交互,主程序再返回继续对端口进行监听,等待下一个客户的连接并与之交互,且可不断如此反复。
当前,支持并发多任务处理的有C++、Delphi、Java等语言开发工具。
Java语言和Java虚拟机提供了完全意义上的多线程机制,其内置语言级的多线程机制可以方便地实现多个并行程序的开发,同时为并发服务器的整体设计提供技术支持。
2基于流技术和Socket的网络通信机制2.1Socket通信原理流式Socket通信是一种基于连接的通信,即在通信开始之前双方确认身份并建立一条专用的虚拟连接通道,然后通过通道以流式的形式传输信息进行通信,通信结束时拆除原先建立起的连接。
在Java中,分别由服务器端的ServerSocket类、客户端的Socket类和Socket.accept()方法实现服务器端和客户端的连接。
2.3.4JAVA多线程技术
多线程机制使应用程序能够并行执行,而且同步机制保证了对共享数据的正确操作。
通过使用多线程,程序设计者可以分别用不同线程完成特定的行为,而不需要采用全局的事件循环机制,这样就很容易地实现网络上的实时交互行为。
一般来说,当运行一个应用程序的时候,就启动了一个进程,当然有些会启动多个进程。
启动进程的时候,操作系统会为进程分配资源,其中最主要的资源是内存空间,因为程序是在内存中运行的。
在进程中,有些程序流程块是可以乱序执行的,并且这个代码块可以同时被多次执行。
实际上,这样的代码块就是线程体。
线程是进程中乱序执行的代码流程。
当多个线程同时运行的时候,这样的执行模式成为并发执行。
当一个服务器应用程序在接收不同的客户端连接时最简单地处理方法就是为每一个客户端连接建立一个线程。
然后监听线程仍然负责监听来自客户端的请求。
如果这种应用程序采用单线程来处理,当监听线程接收到一个客户端请求后,开始读取客户端发来的数据,在读完数据后,read方法处于阻塞状态,也就是说,这个线程将无法再监听客户端请求了。
而要想在单线程中处理多个客户端请求,就必须使用非阻塞的Socket连接和异步I/O.但使用异步I/O方式比使用同步I/O更难以控制,也更容易出错。
因此,使用多线程和同步I/O可以更容易地处理类似于多请求的异步事件。
线程变化转换图如下:
2.3.5连接池技术
连接池技术的核心思想是:
连接复用,通过建立一个数据库连接池以及一套连接使用、分配、管理策略,使得该连接池中的连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。
另外,由于对JDBC中的原始连接进行了封装,从而方便了数据库应用对于连接的使用(特别是对于事务处理),提高了开发效率,也正是因为这个封装层的存在,隔离了应用的本身的处理逻辑和具体数据库访问逻辑,使应用本身的复用成为可能。
连接池主要由三部分组成:
连接池的建立、连接池中连接的使用管理、连接池的关闭。
连接池管理策略是连接池机制的核心。
当连接池建立后,如何对连接池中的连接进行管理,解决好连接池内连接的分配和释放,对系统的性能有很大的影响。
连接的合理分配、释放可提高连接的复用,降低了系统建立新连接的开销,同时也加速了用户的访问速度。
下面介绍连接池中连接的分配、释放策略。
连接池的分配、释放策略对于有效复用连接非常重要,我们采用的方法是一个很有名的设计模式:
ReferenceCounting(引用记数)。
该模式在复用资源方面应用的非常广泛,把该方法运用到对于连接的分配释放上,为每一个数据库连接,保留一个引用记数,用来记录该连接的使用者的个数。
具体的实现方法是:
当客户请求数据库连接时,首先查看连接池中是否有空闲连接(指当前没有分配出去的连接)。
如果存在空闲连接,则把连接分配给客户并作相应处理(即标记该连接为正在使用,引用计数加1)。
如果没有空闲连接,则查看当前所开的连接数是不是已经达到maxConn(最大连接数),如果没达到就重新创建一个连接给请求的客户;如果达到就按设定的maxWaitTime(最大等待时间)进行等待,如果等待maxWaitTime后仍没有空闲连接,就抛出无空闲连接的异常给用户。
当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就删除该连接,并判断当前连接池内总的连接数是否小于minConn(最小连接数),若小于就将连接池充满;如果没超过就将该连接标记为开放状态,可供再次复用。
可以看出正是这套策略保证了数据库连接的有效复用,避免频繁地建立、释放连接所带来的系统资源开销。
连接池的关闭
当应用程序退出时,应关闭连接池,此时应把在连接池建立时向数据库申请的连接对象统一归还给数据库(即关闭所有数据库连接),这与连接池的建立正好是一个相反过程。
2.3.6XML文档技术
XML(theextensiblemarkuplanguage)用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。
用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。
XML是标准通用标记语言(SGML)的子集,非常适合Web传输。
XML提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。
XML与其他数据表现形式最大的不同是:
他极其简单。
这是一个看上去有点琐细的优点,但正是这点使XML与众不同。
XML是用来存储数据的,其焦点是数据的内容。
XML的简单使其易于在任何应用程序中读写数据,这使XML很快成为数据交换的唯一公共语言,虽然不同的应用软件也支持其它的数据交换格式,但不久之后他们都将支持XML,那就意味着程序可以更容易的与Windows,MacOS,Linux以及其他平台下产生的信息结合,然后可以很容易加载XML数据到程序中并分析他,并以XML格式输出结果。
2.3.7JDOM技术
JDOM是一种使用XML的独特Java工具包,用于快速开发XML应用程序。
它的设计包含Java语言的语法乃至语义。
JDOM是对DOM的包装,如果你用过DOM和JDOM开发过的话,你会发现JDOM的api用起来很方便,因为它返回的都是java的collection,它把org.w3c.dom.Document这个类包装了,而且把DOM解析里面还多东西分类了,分成了element,Attrabute等,而在DOM里面全部都是Node,而且用起来很烦。
但是DOM是对xml规范接口的实现,它比JDOM标准,而且他的Dcument就是org.w3c.dom.Document。
JDOM的核心的UML模型:
JDOM是一个开源项目,它基于树型结构,利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作。
JDOM直接为JAVA编程服务。
它利用更为强有力的JAVA语言的诸多特性(方法重载、集合概念以及映射),把SAX和DOM的功能有效地结合起来。
在JDOM中,XML元素就是Element的实例,XML属性就是Attribute的实例,XML文档本身就是Document的实例。
Jdom是用java语言读、写、操作XML的新API函数。
JasonHunter和BrettMcLaughlin公开发布了它的1.0版本。
在直觉、简单和高效的前提下,这些API函数被最大限度的优化。
在接下来的篇幅里将介绍怎么用Jdom去读写一个已经存在的XML文档。
使用前注意事项:
1.JDOM对于JAXP以及TRax的支持;
2.注意在JDOM里文档(Document)类由org.JDOM.Document来表示。
这要与org.w3c.dom中的Document区别开。
第3章.系统的详细设计
3.1系统的基本功能设计
本系统是基于C/S模式设计的,功能主要划分为服务器端和客户端两大模块,在实现过程中主要是从服务器端和客户端两个方面入手的。
3.1.1服务器端基本功能设计
(1)服务管理器
本系统用一个继承与JFrame的类来实现的系统的服务管理器来实现对服务器的管理,进行对服务器的各种功能进行操作。
(2)客户服务程序
要做一个受大众欢迎的软件,仅仅实现基本功能是不够的,很关键的一点就是人机的交互功能,界面不仅美观,还要使用,本系统的功能和界面都是按照人们的操作习惯来实现的。
3.1.2服务器端系统结构图
3.1.3服务器端用例模型设计
3.1.4客户端基本功能设计
(1)申请QQ号码
第一次登陆的用户,可以先打开申请QQ好功能,提交自己的资料到服务器。
申请成功后服务器将QQ号发送给用户。
(2)用户登录
用户登录时,服务器把该用户在线好友和不在线好友的名单发送给用户,客户端将以不同的形式来显示。
(3)好友上下线提示
用户登陆后,用户可以得到用户上线的提示,会在右下角进行提示,在下线的时候也能得到信息,并把其状态改为下线。
(4)获得好友资料
用户登录以后,想在客户端得到好友的资料并显示在聊天主界面上,可以把好友的的QQ号码发送到服务器进行数据库连接从而得到该用户的信息,并发送到客户端进行显示。
(5)发送聊天信息
用户可以给人以一个好友发送信息,不管在线与否,在线的话,会直接发送,不在线的话,会发送到服务器端,当用户登录时,服务器发给该用户。
(6)接受服务器发来的好友信息
用户可以接受好友的聊天信息,包括即时信息和留言。
(7)查看聊天记录
用户登录之后,可以和好友进行聊天可以看到以前的聊天记录。
把聊天记录放在客户端。
(8)接受服务器消息
用户可以接受服务器端发来的信息,例如:
发送文件的信息,用户可以选择是否接受要是不接受的话,就断开,接受的话,就接受。
(9)用户下线
用户下线时,会向服务器发送下线通知,服务器将其状态设为不在线,并通知好友。
3.1.5客户端系统结构图
客户端功能主框架:
3.1.6客户器端用例模型设计
客户端用例关系图:
3.2数据库的设计
数据库设计与实现是该系统开发过程中的一个重要环节,为了设计一个合理有效的数据库,对数据库进行需求分析,概念模型设计,物理模型设计。
3.2.1数据库概念结构设计
数据库用模型进行设计。
3.2.2表的设计
用户信息表(QQ号,用户名,密码,性别,年龄,婚否,邮箱)
好友表(好友QQ号)
聊天信息表(聊天信息)、其中聊天信息是一个打包以后的字符串,里面包含内容有:
消息发送时间,发送者,接受者,发送内容。
3.2.3表在数据库中显示
序号
字段名
含义
数据类型
1
qq
用户的号码
Int
2
nickname
用户的昵称
Varchar()
3
password
用户的密码
Varchar()
4
sex
用户的性别
Char()
5
marriage
用户的婚否
Char()
6
pic
用户的头像
Varchar()
7
email
用户的email
Varchar()
序号
字段意义
名称
数据类型
长度
是否主键
是否允许空
1
好友QQ
friend
varchar
10
是
否
序号
字段意义
名称
数据类型
长度
是否主键
是否允许空
1
好友留言
message
text
300
是
否
3.3XML文档设计
连接数据库文档:
oracle.jdbc.driver.OracleDriver
jdbc:
oracle:
thin:
@192.168.1.27:
1521:
java
scott
tiger
分别表示用户名,密码。
第4章.系统的具体实现
4.1服务器端的实现
4.1.1服务管理器
本系统用一个继承与JFrame的类来实现的系统的服务管理器来实现对服务器的管理,进行对服务器的各种功能进行操作。
4.1.2客户服务程序
要做一个受大众欢迎的软件,仅仅实现基本功能是不够的,很关键的一点就是人机的交互功能,界面不仅美观,还要使用,本系统的功能和界面都是按照人们的操作习惯来实现的。
4.2客户端的实现
4.2.1申请QQ
当用户第一次登陆的时候必须先申请一个QQ号,申请号码的功能在一个继承与JFrame的类中进行实现,代码如下:
packagecom.qq.view;
importjava.awt.Color;
importjava.awt.Font;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.io.IOException;
importjava.io.ObjectInputStream;
importjava.io.ObjectOutputStream;
import.Socket;
import.UnknownHostException;
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;
importjavax.swing.JButton;
importjavax.swing.JComboBox;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
importjavax.swing.JOptionPane;
importjavax.swing.JPasswordField;
importjavax.swing.JTextField;
importcom.goudan.conn.User;
importcom.goudan.conn.UserType;
importcom.goudan.thread.RecevieClientThread;
importcom.goudan.thread.SendClientThread;
importcom.qq.model.ClientMessageDual;
publicclassQqRegextendsJFrame{
publicstaticSockets;
publicstaticObjectInputStreamois;
publicstaticObjectOutputStreamoos;
privateJTextFieldtextField_1;
privateJComboBoxcomboBox_1;
privateJComboBoxcomboBox;
privateJPasswordFieldpasswordField_1;
privateJPasswordFieldpasswordField;
privateJTextFieldtextField;
protectedStringnum;
/**
*@paramargs
*/
publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
QqRegqr=newQqReg();
}
publicQqReg(){
super();
getContentPane().setBackground(Color.ORANGE);
getContentPane().setLayout(null);
finalJLabelnichengLabel=newJLabel();
nichengLabel.setFont(newFont("",Font.PLAIN,14));
nichengLabel.setText("昵称");
nichengLabel.setBounds(44,37,67,22);
getContentPane().add(nichengLabel);
textField=newJTextField();
textField.setBounds(157,30,162,29);
getCon