摘要
计算机发展到现在已经成为一种廉价的生活物品,可以预想到未来人们都会使用计算机,上网的人也会逐渐增多,会有不断的人完善和更新出更好更棒的互联网服务,来提高自己的生活水平。我国近几年经济和社会在不断的发展,互联网也得到了广大的支持,网络更是已经融入了广大人民的日常生活。在计算机编程方面,互联网软件开发逐步转向以java为首的面向对象的编程技术,传统的面向过程的编程技术已经逐渐退出了历史的舞台,java正以不可思议的速度发展。人们日常的生活,教育,网银,网购,面对面的网上视频,以及现在逐渐被大众接受的网络游戏都在使用面向对象的技术。而且java自身的优势以及特点能够真正减少了企业的开发成本和开发人员的开发时间和难度。QQ聊天室使用图形用户界面,能实现一个聊天室中多人聊天,可以两人私聊,可以发送文件。
序言
随着社会的发展和互联网技术的发展,普通老百姓也能够拥有属于自己的计算机,在平常的生活中也离不开了网络技术的支持,而替代了电话和写信的网上即时聊天成为了人们十分常见的沟通方式。本软件是采用sun公司开发提供的java语言制作的,是基于C/S模型的网上聊天室。这个系统分为两个部分,服务端和客户端。服务端的工作主要是来监听和接收来自客户端的请求,然后处理客户端发来的消息,并通知客户端。而客户端的功能是能够让新用户注册,通过用户名密码登陆并且使用该系统。通过服务端和客户端的协同工作最终使用户能够使用网络聊天室,在聊天室中完成用户和用户之间的沟通。
1.需求分析
QQ聊天室使用图形用户界面,能实现一个聊天室中多人聊天,可以两人私聊,可以发送文件。
2.设计思路
2.1根据需求分析,按照结构化设计的要求,得到系统的功能结构图,如图所示。
2.2团队成员负责模块
姓名 | 负责模块 |
王铁凝 | 客户端service包 |
杨晴 | 客户端view包 |
吴佳奕 | 服务端 |
3.详细设计
3.1项目采用技术
文件,多线程。
3.2部分代码呈现
王铁凝:
//文件传输
package Service;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Date;
import qqCommon.Message;
import qqCommon.MessageType;
import qqServer.Utils.MyObjectOutputStream;
import view.ChatFrame;
/**
*
* @author sky
* @version 1.0
*
* 客户端 -- 文件传输类
*
* 该类用于文件传输
*/
public class FileClinetService {
private ChatFrame chatFrame = null;
/** 群发文件方法
*
* @param senderId 发送方
* @param srcPath 本地文件路径
* @param fileName 文件名
* @param chatFrame 聊天界面
*/
public void sendFileToAll(String senderId, String srcPath, String fileName, ChatFrame chatFrame) {
this.chatFrame = chatFrame;
// 若文件名为空, 说明没有选择文件
if(fileName == null) {
return;
}
// 创建message
Message message = new Message();
message.setMessType(MessageType.MESSAGE_File_MES_TOALL); // 设置类型
message.setSender(senderId);
message.setFileName(fileName);
message.setSendTime(new Date().toString()); // 发送时间
// 读取 源文件 路径srcPath
FileInputStream fis = null;
// 获取文件长度 转为int型
byte []fileBytes = new byte[(int)new File(srcPath).length()];
try {
fis = new FileInputStream(srcPath);
fis.read(fileBytes); // 将src源文件 读取到程序数组
// 将字节数组 存入message
message.setFileBytes(fileBytes);
// 发送message 给服务端
ClientConnectThread thread = ClientConnectThreadManage.getThread(senderId, "群聊");
MyObjectOutputStream oos =
new MyObjectOutputStream(thread.getSocket().getOutputStream());
oos.writeObject(message);
// 提示信息
println(senderId + "(我) 发送文件:\t\t " + new Date().toString());
println(" 路径为: " + srcPath + "\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 关闭流
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/** 单发文件方法
*
* @param senderId 发送者id
* @param getterId 接收者id
* @param srcPath 源文件路径
* @param destPath 接收文件存入路径
*/
public void sendFileToOne(String senderId, String getterId, String srcPath, String fileName, ChatFrame chatFrame) {
this.chatFrame = chatFrame;
// 若文件名为空, 说明没有选择文件
if(fileName == null) {
return;
}
// 创建message
Message message = new Message();
message.setMessType(MessageType.MESSAGE_File_MES); // 设置类型
message.setSender(senderId);
message.setGetter(getterId);
message.setFileName(fileName);
message.setSendTime(new Date().toString()); // 发送时间
// 读取 源文件 路径srcPath
FileInputStream fis = null;
// 获取文件长度 转为int型
byte []fileBytes = new byte[(int)new File(srcPath).length()];
try {
fis = new FileInputStream(srcPath);
fis.read(fileBytes); // 将src源文件 读取到程序数组
// 将字节数组 存入message
message.setFileBytes(fileBytes);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 关闭流
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
// 发送message 给服务端
ClientConnectThread thread = ClientConnectThreadManage.getThread(senderId, getterId);
MyObjectOutputStream oos =
new MyObjectOutputStream(thread.getSocket().getOutputStream());
oos.writeObject(message);
// 发送成功 打印
println(senderId + "(我) 发送文件:\t\t " + new Date().toString());
println(" 路径为: " + srcPath + "\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 将内容输出到 chatFrame窗口面板
public void println(String s) {
if (s != null) {
chatFrame.getTxt_Chat().setText(chatFrame.getTxt_Chat().getText() + s + "\n");
System.out.println(s + "\n");
}
}
}
//多线程
public class ClientConnectThreadManage {
// 4.0 线程管理更新
// 将多个线程 放入 HashMap集合, key为用户id value 为线程
private static HashMap<String, HashMap<String, ClientConnectThread>> map = new HashMap<>();
// 一个用户的线程集合 状态 对应线程
private static HashMap<String, ClientConnectThread> stateMap = new HashMap<>();
public static HashMap<String, HashMap<String, ClientConnectThread>> getMap() {
return map;
}
public static HashMap<String, ClientConnectThread> getStateMap() {
return stateMap;
}
// 存放线程 进入集合的方法
public static void addThread(String userId, String state, ClientConnectThread thread) {
stateMap.put(state, thread);
map.put(userId, stateMap);
}
// 根据userId 返回线程
public static ClientConnectThread getThread(String userId, String state) {
return map.get(userId).get(state);
}
// 从集合中删除 某个线程对象
public static void removeThread(String userId) {
map.remove(userId);
}
}
杨晴:
客户端聊天界面
客户端登陆界面
客户端在线用户列表界面
客户端代码主类
用户注册界面
吴佳奕:
4.运行调试与分析讨论
该系统实现的功能:
1.用户注册
2.用户登录
3.用户间私聊
4.用户间群聊
5.拉取在线用户列表
6.用户发送文件
7.服务端推送消息
8.客户端无异常退出
5.git地址
tiening-wang/JavaDesign · GitHub
6.操作演示
操作视频
7.课程设计总结
这次的课程设计让我们受益匪浅。能够这样说,用计算机来解决繁重而低效的手工管理工作,是计算机发展史上的必然。在理论课的学习中,我们掌握了基础课和专业课的理论知识,也曾经做过一些小的程序设计,但真正动手设计一个这种聊天类的软件,还是第一次。在这次的课程设计中,我们曾遇到了许多困难,而在克服这些困难的过程中,我们的各方面的能力又有了很大的提高,使我们的理论知识更好的与实践相结合,增强了专业技能的可实践性。从调研,需求分析到查找资料,结构设计,详细设计以及调试程序。我们终于设计出了一个相对完整的,周密的,可使用的聊天系统。