攀枝花学院
Java程序设计课程设计
题目:聊天程序
学生姓名:Puter
学号:3036
所在院(系):数学与计算机学院
专业:网络工程
班级:2013级网本
指导教师:吴建斌职称:导师
2014 年12 月31 日
攀枝花学院本科学生课程设计任务书
注:任务书由指导教师填写。
目录
摘要 (1)
一、需求分析 (1)
二、概要设计 (3)
三、详细设计............................................4四、调试分析.. (4)
五、结论 (14)
六、实验分工 (14)
七、参考文献 (14)
摘要
在网络越来越发达的今天,人们对网络的依赖越来越多,越来越离不开网络,由此而产生的聊天工具越来越多,例如,国外的ICQ、国内腾讯公司开发的OICQ。基于Java网络编程的强大功能,本次毕业设计使用Java编写一个聊天系统。
一般来说,聊天工具大多数由客户端程序和服务器程序外加服务器端用于存放客户数据的数据库组成,本系统采用客户机/服务器架构模式通过Java提供的Soket类来连接客户机和服务器并使客户机和服务器之间相互通信,由于聊天是多点对多点的而Java提供的多线程功能用多线程可完成多点对多点的聊天,数据库管理系统用SQL Server2000完成并通过JDBC-ODBC桥访问数据库。现在的各种聊天工具功能越来越强大,但是它们的唯一的不足就是必须要联网或者下载到它们的服务端,要不然是没法脱离Intenet使用的。为了能在一个没有连接到Intenet的局域网使用聊天工具,那就必须要有服务器端。
本系统就是包括服务器端与客户端,可以在局域网聊天的一个工具。建立在JAVA平台上,系统的设计使用了面向对象技术和面向对象的设计原则。系统采用C/S结构,客户端与客户端以及客户端与服务器端之间通过Socket传送消息。使用JAVA语言编写,开发工具采用Eclipse。服务器端设计与实现过程中,采用了多线程技术,可以在单个程序当中同时运行多个不同的线程,执行不同的任务。大大增强了程序对服务器资源的利用。
聊天系统完成后将可进行多人对多人的聊天,对好友进行添加、删除,对新用户的注册,发送消息、接受消息等等功能。
关键词:多线程;客户机/服务器;JAVA ; Socket ; Eclipse ; TCP/IP
一、需求分析
为了更好的掌握java这门课程的内容,同时更好的理解与掌握socket编程,对所有面向对象的编程思想以及编程方法的一个总结、回顾和实践,掌握Java语言编程技巧。要求使用图形用户界面。能实现一个聊天室中多人聊天。可以两人私聊。(提示:使用socket通信)程序描述清晰准确,思路清晰,程序能够实现相应的功能。聊天时系统是通过即时通讯技术来实现在线聊天、交流的软件。目前有2种架构形式,1、一种是C/S架构,采用客户端/服务器形式,用户使用过程中需要下载安装客户端软件,典型的代表有:QQ、百度HI 、Skype QQ VS GU、Gtalk、新浪UC、MSN等;2、采用B/S架构,即浏览器/服务端形式,这种形式的即时通讯软件,直接借助互联网为媒介、客户端无需安装任何软件,既可以体验服务器端进行沟通对话,一般运用在电子商务网站的服务商,典型的代表有Websitelive 、53KF、live800等
二、概要设计
目前国内外做聊天系统的公司很多,产品也琳琅满目,国内有诸如腾讯QQ、新浪UC、网易泡泡等,国外有著名的MSN(新版改名为Live Messenger)以及跨平台Gaim等。本人取最具代表性的QQ和MSN进行了一些研究,作为我开发聊天系统的准备。
腾讯无疑是国内即时通讯市场的霸主,自从99年进入即时通讯领域并迅速占市场之后,其在国内用户数量始终高居榜首,即使近几年面对微软MSN的强大攻势,腾讯QQ的时常占有率依然稳步增长。腾讯的成功与其对QQ的不断创新和完善是分不开的。
参考了许多网络上的资料,以及自己通过观察腾讯QQ运行时的各种细节。可以确定腾讯QQ是以多服务器提供服务、服务器总控客户端、客户端之间UDP直连通信的。并且在两个客户端之间不能建立直连的情况下,才由服务器进行中转通信。
其模型如图1-1
图
三、详细设计
通过TCP网络编程,主要编写有客户端与服务器端两个部分,服务器端通过循环一直从客户端接收信息,并通过线程实现多个客户端连接。服务器发送信息则通过定义链表保存客户端信息。每个客户端向服务器发送信息时,则通过链表中的所有客户端的连接而发送信息给所有客户端界面从而实现局域网内多人聊天。而客户端则主要是界面的编写,通过一个线程一直从服务器获取信息,如果不为空时就在界面上显示。
四、调试分析
1、首先运行服务器如图:
图
分析:服务器进入阻塞状态。等待连接。
主要代码:
package class Server { tart();quals(str)){
f = false ;
}else{
ListCO lout = null ;
try {
lout = new ListCO();
} catch (Exception e) {
();
}
Iterator
*/
public static void main(String[] args) {
clientAPP window = new clientAPP();
();
}
/**
* Create the application.
* @return
*/
public void startAPP() { etForeground;
().setFont(new Font("新宋体", , 20));
(700, 320, 450, 300);
;
().setLayout(null);
JLabel lblNewLabel2 = new JLabel("\u8BF7 \u8BBE \u7F6E \u4F60 \u9017 \u540D");
;
;
(new Font("新宋体", , 25));
(108, 23, 226, 50);
().add(lblNewLabel2);
;
(new Font("新宋体", , 22));
(130, 97, 168, 41);
().add(textField_2);
(10);
btnNewButton2 = new JButton("\u8FDB\u5165");
(new Font("微软雅黑", , 30));
;
(145, 165, 127, 41);
().add(btnNewButton2);
(true);
(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
(true); */
private void initialize() { etFont(new Font("楷体", , 18));
().setForeground;
;
("\u8BA8\u8BBA\u7EC4");
(450, 150, 994, 631);
;
().setLayout(null);
JLabel label = new JLabel("\u9017\u6BD4\u804A\u5929\u5BA4");
(new Font("楷体", , 30));
;
(383, 23, 186, 50);
().add(label);
JScrollPane scrollPane = new JScrollPane();
(246, 110, 466, 332);
().add(scrollPane);
;
(new Font("楷体", , 17));
(textArea);
(false);
final JButton btnNewButton = new JButton("\u53D1\u9001");
(new Font("宋体", , 15));
;
(629, 484, 83, 40);
().add(btnNewButton);
textField_1 = new JTextField();
(new Font("楷体", , 17));
(246, 484, 361, 40);
().add(textField_1);
(10);
try {
client = new Socket("localhost",8888) ;
} catch (IOException e) {
();
}
try {
out = new PrintStream()) ;
} catch (IOException e) {
();
}
new Thread(new OutInfo,client)).start(); dd(lblNewLabel);
if() != null){
(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
if() != null){
()+"说:"+());
("");
}
}
});
}
}
}
[2]陈国君等.《Java程序设计基础》(第二版).清华大学出版社
[3] Deitel.《Java大学基础教程》(第六版).电子工业出版社
[4] MaryCampione.《Java语言导学》(第四版).机械工业出版社
[5] Liang.《Java语言程序设计基础篇》(第六版). 机械工业出版社
[6] Kathy Sierra.《Head First Java》(第二版).东南大学出版社
源代码(先启动服务器才能启动客户端,局域网内通讯是客户端的“localhost”改为“服务器所在电脑的IP地址”):
服务器:
package class Server {
private ServerSocket server = null ;
public static List
private Socket client = null ;
private int count = 0 ;
public Server(){
try {
server = new ServerSocket(8888) ;
} catch (IOException e1) {
();
}
"等待服务器被连接······");
boolean flag = true ;
while(flag){
synchronized(this){
try {
client = () ;
count++;
} catch (IOException e1) {
();
}
(client) ;
"第"+count+"客户端被连接!");
try {
new Thread(new ThreadServer(client)).start();
} catch (Exception e) {
();
flag = false ;
}
}
}
try {
();
} catch (IOException e) {
();
}
}
}
package class ServerStart {
public static void main(String[] args) {
new Server();
}
}
package class ThreadServer implements Runnable{
private BufferedReader buf = null ;
private Socket client = null ;
public ThreadServer(Socket client) throws Exception{
= client ;
buf = new BufferedReader(new InputStreamReader ;
}
@Override
public void run(){
String str = null ;
boolean f = true ;
while(f){
try {
str = () ;
} catch (Exception e) {
f = false ;
}
if("bye".equals(str)){
f = false ;
}else{
ListCO lout = null ;
try {
lout = new ListCO();
} catch (Exception e) {
();
}
Iterator
while()){
PrintStream o = () ;
(str);
}
}
}
}
}
package class ListCO {
private List
private List
public ListCO() throws Exception{
= ;
lout = new ArrayList
Iterator
while()){
PrintStream out = null ;
Socket c = () ;
out = new PrintStream()) ;
(out) ;
}
}
public List
return lout;
}
public void setLout(List
= lout;
}
}
客户端:
package class clientAPP {
private JFrame frame;
private JTextField textField_1;
private JTextField textField_2 = new JTextField() ;
private final JTextArea textArea = new JTextArea() ;
JLabel lblNewLabel = new JLabel();
JButton btnNewButton2 = null ;
private Socket client = null ;
private PrintStream out = null ;
private String name ;
/**
* Launch the application.
*/
public static void main(String[] args) {
clientAPP window = new clientAPP();
();
}
/**
* Create the application.
* @return
*/
public void startAPP() {
final JFrame f = new JFrame("聊天帅名") ;
().setForeground;
().setFont(new Font("新宋体", , 20));
(700, 320, 450, 300);
;
().setLayout(null);
JLabel lblNewLabel2 = new JLabel("\u8BF7 \u8BBE \u7F6E \u4F60 \u9017 \u540D");
;
;
(new Font("新宋体", , 25));
().add(lblNewLabel2);
;
(new Font("新宋体", , 22));
(130, 97, 168, 41);
().add(textField_2);
(10);
btnNewButton2 = new JButton("\u8FDB\u5165");
(new Font("微软雅黑", , 30));
;
(145, 165, 127, 41);
().add(btnNewButton2);
(true);
(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
(true);
(false);
("我叫:"+());
}
});
}
public clientAPP() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame("逗比聊天室by Puter");
().setFont(new Font("楷体", , 18));
().setForeground;
;
("\u8BA8\u8BBA\u7EC4");
(450, 150, 994, 631);
;
().setLayout(null);
JLabel label = new JLabel("\u9017\u6BD4\u804A\u5929\u5BA4");
(new Font("楷体", , 30));
;
().add(label);
JScrollPane scrollPane = new JScrollPane();
(246, 110, 466, 332);
().add(scrollPane);
;
(new Font("楷体", , 17));
(textArea);
(false);
final JButton btnNewButton = new JButton("\u53D1\u9001");
(new Font("宋体", , 15));
;
(629, 484, 83, 40);
().add(btnNewButton);
textField_1 = new JTextField();
(new Font("楷体", , 17));
(246, 484, 361, 40);
().add(textField_1);
(10);
try {
client = new Socket("localhost",8888) ;
} catch (IOException e) {
();
}
try {
out = new PrintStream()) ;
} catch (IOException e) {
();
}
new Thread(new OutInfo,client)).start();
;
(new Font("新宋体", , 24));
(29, 115, 180, 40);
().add(lblNewLabel);
if() != null){
(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
if() != null){
()+"说:"+());
("");
}
}
});
}
}
}
package class OutInfo implements Runnable {
private JTextArea t = null ;
private Socket client = null ;
private BufferedReader buf = null ;
public OutInfo(JTextArea t,Socket client){
= t ;
= client ;
}
@Override
public void run() {
boolean flag = true ;
String str = null ;
try {
buf = new BufferedReader(new InputStreamReader())) ;
} catch (IOException e) {
();
}
while(flag){
synchronized(this){
try {
str = () ;
} catch (IOException e) {
();
}
if(str!=null){
(str+"\n");
}
}
}
} }