112 lines
4.1 KiB
Java
112 lines
4.1 KiB
Java
package com.inmind.s_test_11.chatroom1;
|
||
|
||
import java.io.*;
|
||
import java.net.*;
|
||
import java.util.*;
|
||
import java.io.*;
|
||
import java.net.*;
|
||
import java.util.*;
|
||
|
||
public class ChatServer {
|
||
// 服务器监听的端口号
|
||
private static final int PORT = 12345;
|
||
// 存储所有客户端输出流的集合,用于广播消息
|
||
private static Set<PrintWriter> clientWriters = new HashSet<>();
|
||
|
||
public static void main(String[] args) {
|
||
System.out.println("多人聊天服务器启动,监听端口: " + PORT);
|
||
|
||
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
|
||
// 循环接受客户端连接
|
||
while (true) {
|
||
// 阻塞等待客户端连接
|
||
Socket clientSocket = serverSocket.accept();
|
||
System.out.println("新客户端连接: " + clientSocket);
|
||
|
||
// 创建PrintWriter用于向客户端发送消息
|
||
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
|
||
|
||
// 将新客户端的输出流添加到集合中,使用同步块确保线程安全
|
||
synchronized (clientWriters) {
|
||
clientWriters.add(out);
|
||
}
|
||
|
||
// 为每个客户端创建并启动一个新的处理线程
|
||
new Thread(new ClientHandler(clientSocket, out)).start();
|
||
}
|
||
} catch (IOException e) {
|
||
System.err.println("服务器错误: " + e.getMessage());
|
||
}
|
||
}
|
||
|
||
// 客户端处理线程类,负责接收客户端消息并广播
|
||
private static class ClientHandler implements Runnable {
|
||
private Socket clientSocket; // 客户端Socket
|
||
private PrintWriter out; // 向客户端输出的流
|
||
private String username; // 客户端用户名
|
||
|
||
public ClientHandler(Socket socket, PrintWriter out) {
|
||
this.clientSocket = socket;
|
||
this.out = out;
|
||
}
|
||
|
||
public void run() {
|
||
try {
|
||
// 读取客户端发送的数据
|
||
BufferedReader in = new BufferedReader(
|
||
new InputStreamReader(clientSocket.getInputStream()));
|
||
|
||
// 读取客户端发送的用户名
|
||
username = in.readLine();
|
||
System.out.println("用户 " + username + " 加入聊天");
|
||
|
||
// 广播新用户加入的消息
|
||
broadcast(username + " 加入了聊天!");
|
||
|
||
// 循环读取客户端发送的消息
|
||
String input;
|
||
while ((input = in.readLine()) != null) {
|
||
// 如果用户输入exit,退出循环
|
||
if (input.equalsIgnoreCase("exit")) {
|
||
break;
|
||
}
|
||
|
||
// 广播用户发送的消息
|
||
broadcast(username + ": " + input);
|
||
}
|
||
|
||
// 用户退出时的处理
|
||
System.out.println("用户 " + username + " 离开聊天");
|
||
broadcast(username + " 离开了聊天!");
|
||
|
||
} catch (IOException e) {
|
||
System.err.println("与客户端通信错误: " + e.getMessage());
|
||
} finally {
|
||
// 清理资源
|
||
if (out != null) {
|
||
// 从客户端集合中移除当前客户端的输出流
|
||
synchronized (clientWriters) {
|
||
clientWriters.remove(out);
|
||
}
|
||
}
|
||
try {
|
||
// 关闭客户端连接
|
||
clientSocket.close();
|
||
} catch (IOException e) {
|
||
System.err.println("关闭客户端连接错误: " + e.getMessage());
|
||
}
|
||
}
|
||
}
|
||
|
||
// 广播消息给所有连接的客户端
|
||
private void broadcast(String message) {
|
||
// 同步遍历客户端输出流集合,确保线程安全
|
||
synchronized (clientWriters) {
|
||
for (PrintWriter writer : clientWriters) {
|
||
writer.println(message);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|