您的当前位置:首页正文

聊天室Java课程设计

2021-01-29 来源:我们爱旅游


JAVA语言课程设计报告

题 目:Java聊天室 设 计 者: 郭旭 专业班级: 学 号: 指导教师:

2010年12月30日

1.系统需求分析

1.1系统名称: Java聊天室 1.2系统介绍

该系统采用了线程及socket通信技术,使用了Java的图像化界面工具swing,在eclipse开发工具中进行开发。该系统的开发时给予C/S的架构,由客户端与服务器端进行通信,并且在服务器端进行逻辑判断和处理。该系统主要包括登录、注册、添加和删除好友、聊天、查找好友、文件传输等功能模块。

主要用到的技术:Java的图像化开发Swing ,Socket进程通信,Java线程技开发使用的工具:Eclipse中安装swing插件,数据库使用了MySql,并且使用了Navicat实现数据库的可视化操作。

运行环境:该系统以jdk1.6.0_10版本JDK为Java运行环境。 1.3开发背景

在即时聊天工具的出现之前,e-mail一直做为传统的信息交流工具,也是因为e-mail发送和接受消息时间相对滞后的缘故,不能满足人们迅速获取信息的要求。即时通讯工具的产生,为大众提供了一种崭新的综合的信息交流平台。即时通讯不同于传统的通讯工具e-mail,在于它的交流是实时的,使得人们交流更加便捷和快速,满足了人们迅速获取信息的需求,所以深受大众的喜爱,有着很好的发展前景。其中聊天软件就是即时通讯的具体实现。

本系统是一款普通的网络聊天工具,该软件主要有一对一聊天,一对多聊天,文件的传输,信息的保存等功能。系统是基于TCP/IP的网络协议,使用Java Socket进行通信,用现在最流行的网络开发语言Java进行编写实现。 术,Java的输入输出流IO等。

2.系统总体设计

总体结构:使用了典型的C/S架构,如下所示:

客户端 服务端 客户端 3.系统详细设计

3.1数据库设计: 用户表User: 列明 Username Nickname Password Gender Age City Online 好友表Friend: 列明 Id username Friendname 3.2页面设计 3.2.1:登录页面:

用户在登录页面,可以输入用户名和密码进入系统,当然,若用户输入的用户名和密码不正确,系统会给出提示,新用户也可以通过该页面链接到注册页面进行注册,然后回到该页面进行登录

3.2.2:注册页面:

用户在登录页面可以直接登录系统,若是新用户没有登录信息,则会被引导到该页面进行注册,注册新用户时,需要安装一定的规则输入用户信息,有必填项,以及相应的验证。

类型 int varchar varchar 长度 8 32 32 是否为主键 是 外键 外键 描述 标识id 用户名 用户名(好友) 类型 varchar varchar varchar char int varchar char 长度 32 32 32 1 4 32 1 是否为主键 是 描述 用户名 昵称 密码 性别:缺省0 男 年龄 城市 是否在线:缺省0 离线

3.2.3,登录成功后的用户主页面:

用户登录成功之后,在用户的主界面会显示出用户的好友列表等信息,同时也会显示出该用户的好友是否在线等信息。

右键单击用户:

搜索用户,并可以通过该页面添加好友,页面如下:

查看资料:

点击聊天室,可以实现群聊:

3.2.4、服务器端代码: Server.java

package mainserver;

import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Map; /**

* 服务器主线程,负责接收客户端连接,并开启相应线程 响应 *

* 服务器的事务: 0,主线程,负责接收客户端连接,并开启相应线程 响应登陆用户请求 *

* 1,定时检测连接状态,并修改相应的用户状态,如果连接关闭(非正常关闭,例如 网络故障导致;而登陆用户正常退出由子线程负责处理状态的修改。),则 * 将相应用户的状态设为未登陆,以保证同一时刻一个用户只能 登陆一次。 PS:由于主线程无法很好的监控各套接字的状态,因此1该为在子线程中处理 *

* @author Administrator * */

public class Server {

/**

* 服务器参数初始化

private static final int SERVER_PORT = 9999;

public static Map connections = new HashMap* 服务器状态: true:开启 false:关闭 */

private boolean running;

ServiceHandler>();

*/

private void init() { }

public Server() { } /**

* 服务器开启 */

public void start() { }

init(); try { }

startServer(); while (running) { }

Socket socket = null; try { }

System.out.println(\"Listenning... ...\"); socket = serverSocket.accept();

System.out.println(socket.getRemoteSocketAddress()); new ServiceHandler(socket).start(); e.printStackTrace();

serverSocket = new ServerSocket(SERVER_PORT); System.out.println(\"ServerSocket建立失败\"); e.printStackTrace(); return;

} catch (IOException e) {

} catch (IOException e) {

}

public void closeServer() { }

private void startServer() { }

public boolean isRunning() { }

return running; running = true; running = false; System.exit(0);

ServiceHandler.java package mainserver;

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.util.Arrays; import java.util.Iterator; import java.util.List;

import messages.AddFriend; import messages.DelFriend; import messages.Friends; import messages.Info; import messages.Login; import messages.MessageEnd; import messages.Regist; import messages.SearchFriend; import messages.Send; import messages.Update;

import dao.Friend; import dao.FriendDAO; import dao.User; import dao.UserDAO; /**

* 处理单个客户端请求的线程 如果socket读取或发送数据失败,按用户退出登陆处理 *

* @author Administrator * */

public class ServiceHandler extends Thread {

public ServiceHandler(Socket socket) {

this.socket = socket; isOK = true; try { } try {

in = new BufferedReader(new InputStreamReader(socket

.getInputStream()));

out = socket.getOutputStream(); e.printStackTrace(); isOK = false; return;

} catch (IOException e) { private Socket socket; private BufferedReader in; private OutputStream out; private boolean isOK; private String currentUser;

} catch (IOException e) {

e.printStackTrace(); isOK = false;

} /**

}

* 向客户端发送数据 如果发送失败,修改用户状态为未登录 *

* @param msg */

public synchronized void send(String msg) { }

private synchronized String read() { }

String tmp = null; try { }

if (tmp != null) { }

return null;

return tmp; tmp = in.readLine(); e.printStackTrace(); userQuit(); } catch (IOException e) { if (!isOK) { } try { }

System.out.println(\"send: \" + msg); // ShowErrorMsg.display(msg); out.write(msg.getBytes()); out.flush(); userQuit(); return;

} catch (IOException e) {

/**

* 如果读取失败,修改用户状态为未登录 从客户端读取数据 *

* @param socket */

private String receiveTitle() {

StringBuffer buffer = new StringBuffer(); if (!isOK) { }

String tmp = null; try {

if ((tmp = in.readLine()) != null) { return buffer.toString();

}

} else { }

new UserDAO().setOnline(this.currentUser, b);

synchronized (Server.connections) { }

Server.connections.remove(this.currentUser);

/**

* 发送或接收数据失败,修改用户状态 * * @param b */

private void changeUserState(boolean b) {

// 设定为上线 if (b) {

synchronized (Server.connections) { }

Server.connections.put(this.currentUser, this);

}

}

}

buffer.append(tmp);

} catch (IOException e) {

userQuit();

return buffer.toString();

return buffer.toString();

private void userQuit() { }

public void run() {

while (isOK) {

String title = this.receiveTitle(); if (title != null && title.length()!=0) {

if (title.equals(Login.title)) {

System.out.println(\"get: \" + Login.title); System.out.println(this.read()); loginHandle(); this.read(); addFriendHandler(); this.read(); friendsHandler(); this.read(); registHandler(); this.read();

System.out.println(\"失去一个连接。\"); isOK = false;

changeUserState(false);

} else if (title.equals(AddFriend.title)) {

} else if (title.equals(Friends.title)) {

} else if (title.equals(Regist.title)) {

} else if (title.equals(SearchFriend.title)) {

}

}

}

}

searchFriendHandler();

int id = Integer.parseInt(this.read()); sendHandler(id); this.read(); updateHandler(); this.read(); infoHandler(); this.read(); delFriendHandler();

System.out.println(\"nothing catched\");

} else if (title.equals(Send.title)) {

} else if (title.equals(Update.title)) {

} else if (title.equals(Info.title)) {

} else if (title.equals(DelFriend.title)) {

} else {

try { }

socket.close(); e.printStackTrace(); } catch (IOException e) {

private void delFriendHandler() { }

private void infoHandler() {

String user = this.read(); this.read();

new FriendDAO().delete(user, this.currentUser);

this.send(\"success\" + MessageEnd.end + DelFriend.title + MessageEnd.end

+ MessageEnd.end);

}

String username = this.read(); this.read();

User result = new UserDAO().getUserInfo(username); StringBuffer reply = new StringBuffer();

reply.append(\"success\" + MessageEnd.end + Info.title + MessageEnd.end); reply.append(result.getAge() + MessageEnd.end + result.getCity()

+ MessageEnd.end); + MessageEnd.end);

+ result.getUserName() + MessageEnd.end);

reply.append(result.getGender() + MessageEnd.end + result.getNickName() reply.append(result.getPassWord() + MessageEnd.end reply.append(MessageEnd.end); this.send(reply.toString());

private void updateHandler() { }

private void sendHandler(int id) {

String target = this.read(); String content = this.read(); this.read();

if (Server.connections.containsKey(target)) { User user = new User();

user.setUserName(this.currentUser); user.setNickName(this.read()); user.setPassWord(this.read()); user.setCity(this.read());

user.setAge(Integer.parseInt(this.read())); user.setGender(this.read().charAt(0)); new UserDAO().update(user);

this.send(\"success\" + MessageEnd.end + Update.title + MessageEnd.end

+ Messa geEnd.end);

}

}

ServiceHandler hand = Server.connections.get(target); System.out.println(\"connection: \" + target + \"got\"); if (hand != null) { }

System.out.println(\"connection: \" + target + \"got inside\"); hand.send(\"success\"

+

MessageEnd.end

+

\"send\"

+

MessageEnd.end

+ (id) + MessageEnd.end + this.currentUser + MessageEnd.end + content.replace('\\n', '#') + MessageEnd.end + MessageEnd.end);

private void searchFriendHandler() { }

private void registHandler() {

User user = new User(); user.setUserName(this.read());

System.out.println(user.getUserName() + \" read\"); user.setPassWord(this.read()); String name = this.read(); String value = this.read(); this.read();

StringBuffer buffer = new StringBuffer(); buffer.append(\"success\" + MessageEnd.end); buffer.append(SearchFriend.title + MessageEnd.end); List result = new UserDAO().getUserFullName(value); for (int index = 0; index < result.size(); index++) { }

buffer.append(MessageEnd.end); this.send(buffer.toString());

buffer.append(result.get(index) + MessageEnd.end);

}

System.out.println(user.getPassWord() + \" read\"); user.setNickName(this.read());

System.out.println(user.getNickName() + \" read\"); user.setCity(this.read());

System.out.println(user.getCity() + \" read\"); user.setGender(this.read().charAt(0)); user.setAge(Integer.parseInt(this.read())); this.read();

user.setOnline(false);

if (new UserDAO().insertUser(user)) { }

this.send(\"success\" + MessageEnd.end + Regist.title

+ MessageEnd.end + MessageEnd.end);

} else {

this.send(\"fail\" + MessageEnd.end + Regist.title + MessageEnd.end

+ MessageEnd.end);

private void friendsHandler() {

String request = this.read(); this.read();

List result = new UserDAO().getFriends(this.currentUser); System.out.println(\"list start to send\"); StringBuffer sendData = new StringBuffer(); sendData.append(\"success\" + MessageEnd.end); sendData.append(Friends.title + MessageEnd.end);

// this.send(\"success\" + MessageEnd.end+Friends.title + MessageEnd.end); Iterator iterator = result.iterator();

System.out.println(\"send: \" + Arrays.toString(result.toArray()));

private void loginHandle() {

String userName = this.read(); String password = this.read(); System.out.println(userName); private void addFriendHandler() { }

String f = this.read(); this.read();

Friend friend = new Friend(); friend.setFriendName(f);

friend.setUserName(this.currentUser);

new FriendDAO().inser(friend.getFriendName(), friend.getUserName()); this.send(\"success\" + MessageEnd.end + AddFriend.title + MessageEnd.end

+ MessageEnd.end);

// this.send(AddFriend.title + MessageEnd.end + MessageEnd.end); }

if (result.size() == 0) { }

sendData.append(MessageEnd.end); this.send(sendData.toString()); // this.send(MessageEnd.end); System.out.println(\"list send over\");

sendData.append(\"NoFriend\" + MessageEnd.end);

while (iterator.hasNext()) { }

User user = iterator.next();

sendData.append(user.getUserName() + \" \"

+ (user.isOnline() ? \"在线\" : \"离线\") + MessageEnd.end);

// this.send(user.getUserName() + \" \"

// + (user.isOnline() ? \"在线\" : \"离线\") + MessageEnd.end);

}

}

System.out.println(password); this.read();

if (new UserDAO().userLogin(userName, password)) { } else { }

this.send(\"fail\" + MessageEnd.end + Login.title + MessageEnd.end

+ MessageEnd.end);

Server.connections.put(userName, this); this.currentUser = userName; this.changeUserState(true);

this.send(\"success\" + MessageEnd.end + Login.title + MessageEnd.end

+ MessageEnd.end);

4.软件测试

软件实现了基本的登录、注册、聊天、添加好友等功能,相关的测试也围绕着这些功能展开。

其中,在登录模块,进行测试的时候,输入各种情况的字符进行验证,看是否在程序中有漏洞。

在注册模块,验证用户名是否合法,验证用户两次输入的密码是否一致,验证用户输入的年龄是否是合法值。同时在注册模块,还需验证该用户名是否已经存在,避免重复申请等等。

在登录成功之后,要测试软件在功能上是否完全满足设计目标。 综合来看,该系统基本完成既定设计目标。

5.系统总结

以前很少接触到Java的图像化界面编程,运用起来显得有些生疏,做出来的系统界面上不是很美观,系统由于使用了Socket进程间通信以及多线程技术,在程序的并发控制上还有待改进。相较于C/S架构下的程序开发,我还是更倾向和擅长于B/S架构,毕竟,B/S架构下开发是未来开发的一个趋势。

6.参考文献

郑莉 王言行 马素霞 《Java语言程序设计》 北京:清华大学出版社 2005 陈冈, 陈智洁, 宋泽源 Java开发入行真功夫。北京: 电子出版社2009 李茏怡,Java编程实例讲解,高等教育出版社,2005.11 吴晓东 Java程序设计基础 清华大学出版社 2002-5-1 张孝祥 Java基础与案例开发详解 清华大学出版社 2009-9-1 鄢爱兰 Java参考大全 清华大学出版社 2005-11-1

王鹏、何昀峰 Java Swing图形界面开发与案例详解 清华大学出版社 2008-12-1

朱福喜、黄昊 Java项目开发与毕业设计指导 清华大学出版社 2008-6-1

因篇幅问题不能全部显示,请点此查看更多更全内容