OOP思想封装Java在线聊天室群聊版
在线聊天室:服务端
public class Chat {
// private List<Channel> all = new ArrayList<Channel>();
private static CopyOnWriteArrayList<Channel> all = new CopyOnWriteArrayList<Channel>();
public static void main(String[] args) throws Exception {
System.out.println("-----Server-----");
// 1、指定端口使用ServerSocket
ServerSocket server = new ServerSocket(8888);
while (true) {
// 2、阻塞式等待连接accept
Socket client = server.accept();
System.out.println("一个客户端建立了连接");
Channel c = new Channel(client);
all.add(c);// 管理所有的成员
new Thread(c).start();
}
}
// 一个客户代表一个Channel
static class Channel implements Runnable {
private DataInputStream dis;
private DataOutputStream dos;
private Socket client;
private boolean isRunning;
private String username;
public Channel(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
isRunning = true;
// 获取名称
this.username = receive();
// 欢迎您的到来
this.send("欢迎您的到来");
sendOthers(this.username + "来到了聊天室",true);
} catch (IOException e1) {
System.out.println("---1---");
release();
}
}
// 接收消息
private String receive() {
String msg = "";
try {
msg = dis.readUTF();
} catch (IOException e) {
System.out.println("---2---");
release();
}
return msg;
}
// 发送消息
private void send(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
System.out.println("---3---");
release();
}
}
// 群聊:获取自己的消息发给其他人
private void sendOthers(String msg, boolean isSys) {
for (Channel other: all) {
if(other == this){
continue;
}
if(!isSys){
other.send(this.username + ":" + msg); // 群聊消息
}else{
other.send(msg); // 系统消息
}
}
}
// 释放资源
private void release() {
this.isRunning = false;
Utils.close(dis, dos, client);
// 退出
all.remove(this);
sendOthers(this.username + "离开了聊天室...", true);
}
@Override
public void run() {
while (isRunning) {
String msg = receive();
if (!msg.equals("")) {
//send(msg);
sendOthers(msg,false);
}
}
}
}
}
在线聊天室:使用多线程封装了发送端
public class Send implements Runnable{
private BufferedReader console;
private DataOutputStream dos;
private Socket client;
private boolean isRunning;
private String username;
public Send(Socket client,String username){
this.isRunning = true;
this.client = client;
console = new BufferedReader(new InputStreamReader(System.in));
this.username = username;
try {
dos = new DataOutputStream(client.getOutputStream());
// 发送名称
send(username);
} catch (IOException e) {
System.out.println("===1===");
this.release();
}
}
@Override
public void run() {
while(isRunning){
String msg = getStrFromConsole();
if(!msg.equals("")){
send(msg);
}
}
}
// 发送消息
private void send(String msg){
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
System.out.println(e);
System.out.println("===3===");
release();
}
}
/*
* 从控制台获取消息
*/
private String getStrFromConsole(){
try {
return console.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
// 释放资源
private void release(){
this.isRunning = false;
Utils.close(dos,client);
}
}
在线聊天室:使用多线程封装了接收端
public class Receive implements Runnable {
private DataInputStream dis;
private Socket client;
private boolean isRunning;
public Receive(Socket client) {
this.client = client;
this.isRunning = true;
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
System.out.println("===2===");
release();
}
}
// 接收消息
private String receive() {
String msg = "";
try {
msg = dis.readUTF();
} catch (IOException e) {
System.out.println("====4====");
release();
}
return msg;
}
@Override
public void run() {
while(isRunning){
String msg = receive();
if(!msg.equals("")){
System.out.println(msg);
}
}
}
// 释放资源
private void release() {
this.isRunning = false;
Utils.close(dis, client);
}
}
在线聊天室:客户端
public class Client {
public static void main(String[] args) throws Exception {
System.out.println("-----Clinet-----");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入用户名:");
String username = br.readLine();
// 1、建立连接:使用Socket创建客户端 + 服务端的地址和端口
Socket client = new Socket("localhost",8888);
// 2、客户端发送消息
new Thread(new Send(client,username)).start();
new Thread(new Receive(client)).start();
}
}