多人聊天室设计毕业论文

目录

第1章绪论 (2)

1.1选题背景 (2)

1.2目的和意义 (2)

第2章系统概况 (3)

2.1系统主要功能 (3)

2.2系统所用技术 (3)

2.2.1 Java技术 (3)

2.2.2 TCP/IP协议 (4)

2.2.3 JMF使用RTP协议 (4)

2.2.4 Mysql数据库 (4)

2.3系统运行环境 (4)

第3章系统分析 (5)

3.1关于系统分析 (5)

3.1.1可行性分析 (5)

3.2系统功能分析 (5)

3.2.1客户端功能分析 (5)

3.2.2 服务器功能分析 (6)

3.3系统流程图 (6)

第4章系统设计 (8)

4.1数据库表设计 (8)

4.2 自定义XMPP协议 (8)

第5章系统实现 (10)

5.1 客户端实现 (10)

5.1.1 登录界面 (10)

5.1.2 用户列表界面 (13)

5.1.3 聊天窗口及视频界面 (15)

5.2 服务器端实现 (20)

5.2.1 服务器界面 (20)

第6章结束语 (21)

参考文献 (22)

多人聊天室设计

摘要:在信息时代的今天,进行信息交流已成为了人们日常生活中不可缺少的事

情,但是由于手机话费的昂贵、发送手机短信的烦琐,以及它们之间由于不及时性而造成了相应的损失;网络通信软件由于安装方便、操作简单,更重要的是它给广大的用户提供了一个免费交流的平台,这个平台具有广域性、及时性、高效性,因此受到了许多公司、企业院校的青睐,特别是广大青年人的追捧;本论文介绍的就是一个基于TCP/IP协议、C/S模式、利用多线程、实现点对点通信的一个多人聊天室软件,可以进行私聊、群聊、视频聊天等;

关键字:Java;聊天室;线程;协议;

第1章绪论

1.1选题背景

随着信息时代的到来,信息的交流量也与日俱增。尽管一些通信工具,例如手机,可以通过打电话或者发短信与对方进行相应的信息交流;但是对于大量的信息、长时间或者“面对面”的交流,手机则不能适应。

网络通信软件,正是由于它的安装方便,只需要彼此之间都有连上网的电脑,安装有相应的客户端,就可以进行信息交流;并且它可以实现与一个人与多个不同国家、地方的人进行交流,交流的过程中可以传输大量的信息资料,更加的方便快捷,也无需过多的通信费用;甚至彼此之间还可以通信视频实现“面对面”的语音聊天,提供了更加亲舒适的服务;

因此许多的公司、企业及院校都有相应的网络通信软件,进行日常的信息处理。特别受青少年追捧的网络通信软件就是腾讯公司的QQ,本论文所介绍的多人聊天室就是在腾讯QQ的基础上自己制作的一个实现了相应功能的网络通信软件;

1.2目的和意义

1.网络通信软件可以为公司、企业及院校提供日常的信息处理服务。可以解决信息交流中的信息量大繁多,及时性,广域性等相应的问题,为企业内部的凝聚,与外界的交流以及以后的发展带来了不可磨灭的功劳;

2.网络通信软件也给用户的日常生活带了方便。用户可以通过这种通信软件找到自己的知己,并且可以和他们交流自己的知识,兴趣爱好等,也可以和自己的亲戚、朋友、同学可以在聊天室里畅所欲言;

第2章系统概况

2.1系统主要功能

1.用户登录:用户只有输入正确的用户账号、密码才有权利进入到聊天室,输入错误则会出现相应的提示;

2.聊天:用户指定相应的在线用户,输入信息,点击发送按钮,即可将信息发送给对方;

3.窗口抖动:聊天时点击抖动按钮,即可使聊天对方的窗口出现一定时间的抖动效果;

4.视频聊天:聊天双方在有视频的基础上,可以通过视频来进行“面对面”的聊天;

2.2系统所用技术

2.2.1 Java技术

Java是Sun公司于1995年推出的程序设计语言。Java分为三个体系J2SE(Java平台标准版)、J2EE(Java平台企业版)和J2ME(Java平台微型版)。Java 语言之所以发展这么迅速,主要在于它跨平台、开源,在Java里面很多项目都是开源的,就像Linux一样,也可以说是开源推动了它的进一步发展。

Java在现在依然是很火的一门编程语言,主要在于它有如下特点:

1.Java语言是简单的。它相对于C或C++来说比较简单,它丢掉了C或

C++里面的指针。

2.它是面向对象的。在Java中可以认为万事万物皆对象。

3.Java语言是分布式的。Java语言支持Internet应用的开发,在

基本的Java应用编程接口中有一个网络应用编程接口(java

net),它提供了用于网络应用编程的类库,包括URL、

URLConnection、Socket、 ServerSocket等。Java的RMI(远程

方法激活)机制也是开发分布式应用的重要手段。

4.Java语言也是动态的。Java语言的设计目标之一是适应于动态变

化的环境。Java程序需要的类能够动态地被载入到运行环境,也

可以通过网络来载入所需要的类。这也有利于软件的升级。另外,

Java中的类有一个运行时刻的表示,能进行运行时刻的类型检

查。

2.2.2 TCP/IP协议

TCP/IP(Transmission Control Protocol/Internet Protocol)的简写,中文译名为传输控制协议/因特网互联协议,又叫网络通讯协议,这个协议是Internet最基本的协议、Internet国际互联网络的基础,简单地说,就是由网络层的IP协议和传输层的TCP协议组成的。TCP/IP 定义了电子设备(比如计算机)如何连入因特网,以及数据如何在它们之间传输的标准。TCP/IP 是一个四层的分层体系结构。高层为传输控制协议,它负责聚集信息或把文件拆分成更小的包。低层是网际协议,它处理每个包的地址部分,使这些包正确的到达目的地。

在多人聊天室中则是在这种协议基础上实现的彼此之间的信息交流;

2.2.3 JMF使用RTP协议

实时传输协议RTP(Real-Time Transport Protocol)是针对Internet上多媒体数据流的一个传输协议,由IETF(Internet工程任务小组)作为RFC1889发布。RTP被定义为在一对一或一对多的传输情况下工作,其目的是提供时间信息和实现流同步。RTP的典型应用建立在UDP上,但也可以建立在TCP或ATP等其它协议之上工作。RTP本身只保证实时数据的传输,并不能为按顺序传送数据包提供可靠的传送机制,也不提供流量控制或拥塞控制,它依靠RTCP提供这些服务。

在多人聊天室中则是在这种通信协议的基础上实现的视频聊天;

2.2.4 Mysql数据库

MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL 数据库系统使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理。并且其速度、可靠性和适应性都非常不错,而且还有可视化的插件,便于建表和进行其它的操作。多人聊天室中利用这种数据库实现的数据保存;

2.3系统运行环境

硬件环境:个人计算机(内存1G+)

软件环境:Eclipse 3.3 、JDK 1.6、Mysql 5.0 、Windows XP

第3章系统分析

3.1关于系统分析

3.1.1可行性分析

本软件在计算机语言上采用的是当前流行的Java语言,这种语言具有很好的跨平台性,可以对不同的操作系统进行兼容,只需要用户的电脑上将有SUN公司开发的JDK1.4以上的版本就可以运行该程序;编辑器利用是Eclipse,这种编辑器具有很好的提示功能,支持插件,使用相当方便;数据库利用的是Mysql,这种数据库易于安装,所占的空间少,启动快,适合在局域网;该软件只需要一台将有JDK1.4以上版本的电脑即可,经济上实惠;由于电脑技术的发展,人们素质的提高,对于电脑的基本操作和维护都有了一定的基础,因此在维护上还是不成问题;

3.2系统功能分析

3.2.1客户端功能分析

在客户端我们根据软件的需要可以从它所应具有的界面个数来对它的功能进行分析;

第一个登录界面

在这个界面上,有两个输入框一个是账号,一个是密码;当输入完信息之后,点击登录按钮,客户端就会开始与服务器与行连接;在这个过程中要完成两件事情。一件是,客户端取得与服务器的连接,如果服务器没有开启或者网络不通,自然要给客户端一个友好的提示信息;另一件是,取得连接之后客户端将账号及密码信息发送给服务器,以确保该用户是否存在,如果不存在则提示账号或者密码错误,存在则进入下一个界面,进度条则会显示整个处理的进度情况;

第二个用户列表界面

这个界面是用户成功登录之后,展现该用户自己信息及所有好友信息的界面,这是每一个用户都必须有的界面,只有退出整个程序时这个界面才会消息;在这个界面上提供给用户进行操作的则是,用户可以根据自己的喜爱选择好友列

表中相应的好友,双击头像图标进行聊天;

第三个聊天窗口

这是整个多人聊天室的主要界面;这在这界面上负责将自己的消息通过发达信息框发送给对方,并将对方的信息显示在信息显示框内;另外这个窗口还有相应的功能按钮提供给用户一些方便的操作。例如抖动按钮,发送按钮,视频聊天选项等;点击视频聊天选项会出现相应的视频聊天窗口,点击发送按钮会将消息发送出去,点击抖动按钮会使聊天对方的聊天窗口出现一段时间的抖动;

3.2.2 服务器功能分析

服务器的主要功能则是将客户端发送过来的信息,进行验证和转发,服务器处理的工作较多,要求性能较好;在服务器端主要有一个界面,这个界面负责启动服务器,并且在服务器启动之后,会将所有存在的用户信息包括账号、密码、头像等信息显示在表格上,以方便后台的人员对用户进行相应的操作;另外所有用户发送给客户端的信息都会在信息显示框内进行显示,以便查看整个通信过程;

3.3系统流程图

为了更清楚地说明系统框架,以便更好地说明设计该系统的解决方案,我们给出了系统流程图,如图3.1。系统流程图展示了该系统客户端与服务器之间的逻辑关系,其中主要介绍的是服务器如何处理消息的一个过程,并将在下面的的系统设计阶段给出了相应的消息设计(XMPP)。

Client

Server

1.建立联接,发送注册消息2。注册应答

N Client Y Server

3。登录消息

4。登录应答N

账号、密码错误Client Server

Y 5。在线用户队列数据库

数据

数据

Client1Client2Client3。。。

处理线程

处理线程

处理线程

私聊、抖动、视频及相关消息

图3.1

由上图可以看出,一个客户端只要能过了账号、密码的验证就可以与其它相应的客户端取得联系,进行彼此之间的交流。而服务器为了单独处理第个客户端则利用了多线程技术,使得每个客户端的信息不至于混乱;

第4章系统设计

4.1数据库表设计

user 表:

id 整型唯一ID

name 字符型用户名

account 字符型账号

password 字符型密码

picture 字符型头像

friends 表:通过friends 表可以找到某个用户的所有朋友信息

id 整型唯一ID

id_user 字符型外键

type 字符型朋友类型

friend_account 字符型朋友账号

4.2 自定义XMPP协议

1------>客户端与服务器连接

a.没有连接上则返回超时,

b.连接上密码错误则进行提示

正确则返回个人信息、用户列表并进入用户窗口

1-1 . 登录请求

login

账号

密码

1-2 . 登录应答

login_response

1表示成功,0表示失败

1-3 . 发送个人信息

user用户名用户账号用户头像

1-4 . 发送好友队列信息---默认2个组

好友类型

好友名

好友账号

好友头像

2 . 聊天

彼此在线,好友发送消息过来时,弹出对应的聊天框

2-1.

chat

本人账号

朋友账号

内容

对方不在线时,给发送者提示

2-2.

line

-1

不在线好友账号

3 . 抖动

点击抖动按钮则可以让对方的聊天框出现一段时间的抖动,条件是该好友要在线

3-1.

shake

发送方账号

接收方账号

4. 视频

4-1 视频请求(点击开始视频按钮)

vidio

发送方账号

接收方账号

发送者的ip,port

4-2 视频应答(点击接受按钮)

r_vidio

发送方账号

接收方账号

发送者的ip,port

第5章系统实现

5.1 客户端实现

5.1.1 登录界面

关键代码:

private void creatFrame() {

this.setTitle("QQ2011");

this.setSize(340, 250);

// 三个panel--加中一个布局管理器给图片定位

JPanel pan1 = new JPanel(new java.awt.FlowLayout(0, 0, 0));

JPanel pan2 = new JPanel();

JPanel pan3 = new JPanel(new java.awt.FlowLayout(0, 10, 3));

// pan2上的三个jpanel

JPanel pan4 = new JPanel();

JPanel pan5 = new JPanel();

JPanel pan6 = new JPanel();

// pan1上的标签---要标签上加一张图片

JLabel lab1 = new JLabel();

javax.swing.ImageIcon img1 = new

javax.swing.ImageIcon(

"images//login1.jpg");

lab1.setIcon(img1);

// 在三个jpanel上设图片和背景

pan1.add(lab1);

pan2.setBackground(new java.awt.Color(228, 244, 255));

pan3.setBackground(new java.awt.Color(194, 255, 250));

// 设组件

JLabel name_label = new JLabel("账号:");

name_label.setFont(new java.awt.Font("宋体",

Font.TRUETYPE_FONT, 12));

text = new JTextField(15);

JLabel reg_label = new JLabel(" 注册账号");

reg_label.setFont(new java.awt.Font("宋体",

Font.TRUETYPE_FONT, 12));

JLabel pwd_label = new JLabel("密码:");

pwd_label.setFont(new java.awt.Font("宋体",

Font.TRUETYPE_FONT, 12));

pwd = new JPasswordField(15);

JLabel mod_label = new JLabel(" 修改密码");

mod_label.setFont(new java.awt.Font("宋体",

Font.TRUETYPE_FONT, 12));

// 进度条

JProgressBar bar = new JProgressBar();

JProBar prob=new JProBar(bar);

//启动进度条

prob.start();

bar.setBackground(Color.red);

JLabel bar_label = new JLabel(" ");

JButton set_bt = new JButton("设置");

set_bt.setSize(60, 5);

set_bt.setFont(new java.awt.Font("宋体",

Font.TRUETYPE_FONT, 12));

JLabel empty_label = new JLabel(

" ");

// 给登录按钮、密码输入框注册侦听器

JButton log_bt = new JButton("登录");

LoginButtonListener listener = new

LoginButtonListener(this);

log_bt.addActionListener(listener);

pwd.addActionListener(listener);

log_bt.setSize(60, 5);

log_bt.setFont(new java.awt.Font("宋体",

Font.TRUETYPE_FONT, 12));

// 将组件加到pan4,pan5,pan6,pan3上

pan4.add(name_label);

pan4.add(text);

pan4.add(reg_label);

pan5.add(pwd_label);

pan5.add(pwd);

pan5.add(mod_label);

pan6.add(bar);

pan6.add(bar_label);

pan3.add(set_bt, BorderLayout.WEST);

pan3.add(empty_label, BorderLayout.CENTER);

pan3.add(log_bt, BorderLayout.EAST);

// pan4,pan5,pan6加到pan2上

pan2.add(pan4, BorderLayout.NORTH);

pan2.add(pan5, BorderLayout.CENTER);

pan2.add(pan6, BorderLayout.SOUTH);

// 三个jpanel的位置北中

this.add(pan1, BorderLayout.NORTH);

this.add(pan2, BorderLayout.CENTER);

this.add(pan3, BorderLayout.SOUTH);

this.setDefaultCloseOperation(3);// 关闭窗口时退出运行

this.setLocationRelativeTo(null);// 位于窗口的中间

this.setVisible(true);// 可视

this.setResizable(false);// 设定窗口不可改变大小}

5.1.2 用户列表界面

关键代码:

private JTree getJTree0() {

if (jTree0 == null) {

jTree0 = new JTree();

DefaultTreeModel treeModel = null;

{ // 根结点

DefaultMutableTreeNode root = new DefaultMutableTreeNode("好友列表");

// 根据好友列表建树

// 第一层,好友类型

for (int i = 0; i < 2; i++) {

DefaultMutableTreeNode node1 = new DefaultMutableTreeNode(

data[i][0]);

// 第二层,好友名字

for (int j = 0; j < 1; j++) {

DefaultMutableTreeNode node2 = new DefaultMutableTreeNode(

data[i][1]);

node1.add(node2);

}

root.add(node1);

}

// 表模型

treeModel = new DefaultTreeModel(root);

}

// 给叶节点加上图片

ImageIcon image = new ImageIcon("images/163.gif");

DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();

renderer.setLeafIcon(image);

jTree0.setCellRenderer(renderer);

// 给节点加上双击事件

jTree0.addMouseListener(new MouseAdapter() {

public void mouseClicked(MouseEvent e) {

if (e.getClickCount() == 2) {

// 点击路径

TreePath path =

jTree0.getPathForLocation(e.getX(), e

.getY());

// 根据路径得到节点

TreeNode node = (TreeNode)

path.getLastPathComponent();

// 叶节点1

if((node.toString()).equals(data[0][1])) {

if (frame == null) {

frame = new

ChatFrame(1,data,per,session);

}

}

// 叶节点2

if((node.toString()).equals(data[1][1])) {

if (frame2 == null) {

frame2 = new

ChatFrame(2,data,per,session);

}

}

}

}

});

jTree0.setModel(treeModel);

}

return jTree0;

}

5.1.3 聊天窗口及视频界面

FMJ 视频聊天室的实现

视频聊天整体结构分析

整体流程图示:

Network DataSource Processor

DataSource SendStream RecieveStream

DataSource Processor

CCD

MIC

RTP

RTP 服务器和客户机通过基于UDP 的RTP 通信协议传输媒体流数据,在建立RTP

会话之前,先建立一个Socket 连接,以发送接收其它请求消息,如要发送多媒体数据的请求和应答消息。发送视频请求消息和完成应答之后,服务器利用客户机发上来的消息建立RTP 会话,因此在视频请求的消息中应包含客户机的地址、端口等消息,以供服务器建立RTP 会话。客户机也要和服务器建立对应的RTP 会话,这样,视频数据流就可以通过RTP 会话传输: Server Client

启动服务器,创建ServerSocket,等待客户机连接接收到请求接收视频的消息,建立RTP 会话,打开RTP 事件监听接收视频数据并在本地播放开启客户机,连接服务

向服务器发送传输视频

请求

建立Socket 连接发送数据消息告知数据已接收

建立RTP 会话,开始传送

视频数据发送视频数据

停止传送视频数据,删

除RTP 会话

发送停止接收消息停止接收视频数据关闭连接,准备其它会

话继续监听其它客户端的

连接

关键代码:

/**

* 本地播放的方法

* @param :dataSource 要初始化的数据源

*/

public void playSource() {

try {

// 创建一个播放器对象

player =

javax.media.Manager.createPlayer (dataSource );

// 创建一个播放器的控制器监听器对象

MyRTPListener l = new MyRTPListener(player , ServerStart.jf ,

ServerStart.panel );

// 给播放器对象注册控制器监听器

player .addControllerListener(l);

// 开始播放

player .start();

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 实现监听器接口中的方法.此方法可通知应用程序对播放器的事件做出

反应

*/

public synchronized void

controllerUpdate(ControllerEvent e) {

if (e instanceof javax.media.RealizeCompleteEvent) { Component comp;

// 得到播放器的可视容器,即播放器显示视频的容器

if ((comp = player.getVisualComponent()) != null) {

// 将可视容器加到窗体上

panel.add("Center", comp);

}

// 得到播放器的控制面板容器

if ((comp = player.getControlPanelComponent()) != null) {

// 添加到窗体上

panel.add("South", comp);

}

// 刷新窗体

jf.validate();

}

}

/**

*初始化RTP会话

*

*@return

*/

protected boolean initialize() {

try {

mgrs = new RTPManager[sessions.length];

SessionLabel session;

// 打开会话

for (int i = 0; i < sessions.length; i++) {

// 解析会话地址

try {

session = new SessionLabel(sessions[i]);

} catch (IllegalArgumentException e) {

System.err

.println("Failed to parse the session address given: "

+ sessions[i]);

return false;

}

System.err.println(" - Open RTP session for: addr: "

+ session.addr + " port: " + session.port + " ttl: "

+ session.ttl);

mgrs[i] = (RTPManager)

RTPManager.newInstance();

mgrs[i].addSessionListener(this);

mgrs[i].addReceiveStreamListener(this);

// 初始化 RTPManager用 RTPSocketAdapter

mgrs[i].initialize(new

RTPSocketAdapter(InetAddress

.getByName(session.addr), session.port, session.ttl));

BufferControl bc = (BufferControl) mgrs[i] .getControl("javax.media.control.BufferControl");

if (bc != null)

bc.setBufferLength(350);

}

} catch (Exception e) {

System.err.println("Cannot create the RTP Session: "

+ e.getMessage());

return false;

}

// 等待数据到达.

long then = System.currentTimeMillis();

long waitingPeriod = 30000; // wait for a maximum of 30 secs.

try {

synchronized (dataSync) {

while (!dataReceived

&& System.currentTimeMillis() - then < waitingPeriod) {

if (!dataReceived)

System.err

.println(" - Waiting for RTP data to arrive");

dataSync.wait(1000);

}

}

} catch (Exception e) {

}

if (!dataReceived) {

System.err.println("No RTP data was received.");

close();

return false;

}

return true;

}

5.2 服务器端实现

5.2.1 服务器界面

关键代码:

/**

*处理客户端端来的消息

*/

private void readFromClient() {

while (true) {

try {

// 读取客户端的消息--截取消息类型

r_msg = readMsg(ins);

String type = Xmpp.getXMLValue(r_msg, "type");

// ............ 根据消息类型

// ------------进行处理

// 1.登录消息

if (type.equals("login")) {

loginMsg();

相关文档
最新文档