思维导图---建议下载文件查看
多用户通信系统(Chat).xmind-Java文档类资源-CSDN文库
客户端
ConnectThread
package Chat.common;
import java.io.Serializable;
/**
* @author whlie(true){learn}
* 表示客户端与服务器端通信时的对象
*
*/
public class Message implements Serializable {
private static final long serialVersionUID =1L;
//发送者
private String sender;
//接收者
private String getter;
//消息内容
private String content;
//发送时间
private String senderTime;
//消息类型(可以在接口定义消息类型)
private String mesType;
//和文件相关的成员
private byte[] fileBytes;
private int fileLen=0;
//将文件传输在哪里
private String dest;
//源文件路径
private String src;
public byte[] getFileBytes() {
return fileBytes;
}
public void setFileBytes(byte[] fileBytes) {
this.fileBytes = fileBytes;
}
public int getFileLen() {
return fileLen;
}
public void setFileLen(int fileLen) {
this.fileLen = fileLen;
}
public String getDest() {
return dest;
}
public void setDest(String dest) {
this.dest = dest;
}
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getGetter() {
return getter;
}
public void setGetter(String getter) {
this.getter = getter;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getSenderTime() {
return senderTime;
}
public void setSenderTime(String senderTime) {
this.senderTime = senderTime;
}
public String getMesType() {
return mesType;
}
public void setMesType(String mesType) {
this.mesType = mesType;
}
}
Manage
package Chat.Client;
import java.util.HashMap;
/**
* @author whlie(true){learn}
* 管理客户端连接到服务端的线程的类
*/
public class Manage {
//将多个线程加入集合(用户名,线程)
private static HashMap<String,ConnectThread> hm=new HashMap<>();
public static void add(String userId,ConnectThread connectThread){
hm.put(userId,connectThread);
}
//通过用户名得到对应的线程
public static ConnectThread get(String userId){
return hm.get(userId);
}
}
Service
package Chat.Client;
import Chat.common.*;
import java.io.*;
import java.net.*;
/**
* @author whlie(true){learn}
* 完成用户登录验证和用户注册
*/
public class Service {
//因为在其他地方也会用到,所以生成属性
private User user=new User();
private Socket socket=null;
private boolean flag=false;
public boolean check(String userId,String password){
user.setUserId(userId);
user.setPassword(password);
//连接服务器发送User对象
try {
socket=new Socket(InetAddress.getLocalHost(),9999);
//将User对象发送到服务器
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(user);
//读取返回的Massage对象
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Message message = (Message) ois.readObject();
//判断是否登录成功
if (message.getMesType().equals(MessageType.LONGIN_SUCCESS)){
//创建一个和服务器保持通信的线程
ConnectThread connectThread = new ConnectThread(socket);
//启动线程
connectThread.start();
//为了便于管理,将多个线程加入集合
Manage.add(userId,connectThread);
flag=true;
}else {
//如果登录失败就无法启动线程,关闭socket
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
//向服务器请求返回在线用户列表,获取之前我们要确定是哪个客户发出的请求
public void online(){
//构建Message对象并发送请求
Message message = new Message();
message.setMesType(MessageType.GET_ONLINE);
message.setSender(user.getUserId());
//拿到对象输出流
try {
ObjectOutputStream oos =
//逐层去取,先从集合中取出线程,再从线程中取出socket,再从socket中取出输出流
new ObjectOutputStream(Manage.get(user.getUserId()).getSocket().getOutputStream());
//发出请求
oos.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
}
//退出客户端
public void out(){
Message message = new Message();
message.setMesType(MessageType.EXIT);
//指明是哪个客户端要退出
message.setSender(user.getUserId());
//发送给服务器
try {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(message);
System.out.println(user.getUserId()+"已退出系统");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Fileto
package Chat.Client;
import Chat.common.Message;
import Chat.common.MessageType;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
/**
* @author whlie(true){learn}
* 该类/对象完成文件传输
*/
public class Fileto {
/**
*
* @param src 源文件
* @param dest 把该文件传输到那个目录
* @param sendId 发送用户Id
* @param getterId 接收用户Id
*/
public static void send(String src, String dest, String sendId, String getterId){
//读取src文件-->message
Message message = new Message();
message.setMesType(MessageType.FILE);
message.setSender(sendId);
message.setGetter(getterId);
message.setSrc(src);
message.setDest(dest);
//读取文件
FileInputStream input=null;
byte[] bytes=new byte[(int)new File(src).length()];
try {
input= new FileInputStream(src);
//将src文件读入到程序的字节数组
input.read(bytes);
//设置文件对应的字节数组
message.setFileBytes(bytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭
if(input!=null){
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//发送
try {
ObjectOutputStream oos = new ObjectOutputStream(Manage.get(sendId).getSocket().getOutputStream());
oos.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
//提示信息
System.out.println("\n"+sendId+"给"+getterId+"发送文件:"+src+"到目录"+dest);
}
}
Service1
package Chat.Client;
import Chat.common.Message;
import Chat.common.MessageType;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Date;
/**
* @author whlie(true){learn}
* 该类提供与消息相关的方法:私聊,群发等
*/
public class Service1 {
/**
*
* @param content 内容
* @param sender_id 发送者
* @param getter_id 接收者
*/
public void Private_chat(String content,String sender_id,String getter_id){
Message message = new Message();
message.setMesType(MessageType.COMMON_MES);
message.setSender(sender_id);
message.setContent(content);
message.setGetter(getter_id);
//发送时间
message.setSenderTime(new Date().toString());
System.out.println(sender_id+"对"+getter_id+"说:"+content);
//发向服务器
try {
ObjectOutputStream oos = new ObjectOutputStream(Manage.get(sender_id).getSocket().getOutputStream());
oos.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
* @param content 发送内容
* @param sender_id 发送人
*/
public void Group(String content, String sender_id){
Message message = new Message();
message.setMesType(MessageType.GROUP);
message.setSender(sender_id);
message.setContent(content);
System.out.println(sender_id+"对大家"+"说:"+content);
//发向服务器
try {
ObjectOutputStream oos = new ObjectOutputStream(Manage.get(sender_id).getSocket().getOutputStream());
oos.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
ClientView
package Chat;
import Chat.Client.Fileto;
import Chat.Client.Service;
import Chat.Client.Service1;
import Chat.tool.Utility;
/**
* @author whlie(true){learn}
*/
@SuppressWarnings({"all"})
public class ClientView {
//控制是否显示菜单
private boolean flag =true;
//接收用户输入
private String key="";
//用于登录服务和注册用户
private Service service=new Service();
//用于消息的私发...
private Service1 service1=new Service1();
//用于文件传输
private Fileto file=new Fileto();
//显示主菜单
public static void main(String[] args) {
new ClientView().mainMenu();
System.out.println("客户端退出系统...");
}
private void mainMenu(){
while(flag){
System.out.println("=========欢迎登录网络通信系统=========");
System.out.println("\t\t 1 登录系统");
System.out.println("\t\t 9 退出系统");
System.out.print("请输入选项:");
key= Utility.readString(1);
switch(key){
case "1":
System.out.print("请输入用户名:");
String userId=Utility.readString(20);
System.out.print("请输入密 码:");
String password=Utility.readString(20);
//前往服务器判断该用户是否存在
if (service.check(userId,password)){
System.out.println("\n=========欢迎用户("+userId+")=========\n");
//进入二级菜单
while(flag){
System.out.println("=========网络通信系统二级菜单(用户"+userId+")=========");
System.out.println("\t\t 1 显示在线用户列表");
System.out.println("\t\t 2 群发消息");
System.out.println("\t\t 3 私发消息");
System.out.println("\t\t 4 发送文件");
System.out.println("\t\t 9 退出系统");
System.out.print("请输入选项:");
key=Utility.readString(1);
switch(key){
case "1":
service.online();
break;
case "2":
System.out.print("请输入要对大家说的话:");
String content1 = Utility.readString(30);
service1.Group(content1,userId);
break;
case "3":
System.out.print("请输入用户号:");
String getterid = Utility.readString(20);
System.out.print("请输入内容:");
String content = Utility.readString(30);
service1.Private_chat(content,userId,getterid);
break;
case "4":
System.out.println("请输入接收用户:");
getterid=Utility.readString(50);
System.out.println("请输入文件所在路径(d:\\\\xx.jpg)");
String src=Utility.readString(100);
System.out.println("请输入存放路径(d:\\\\yy.jpg)");
String dest=Utility.readString(100);
Fileto.send(src,dest,userId,getterid);
break;
case "9":
flag=false;
service.out();
break;
}
}
}else {
System.out.println("=========登录失败=========");
break;
}
case "9":
flag=false;
System.out.println("退出系统");
break;
}
}
}
}