Java网络编程实战(多人聊天室-CS模式)
一、C/S模式核心原理
1.1 基本架构
C/S(Client/Server)模式采用客户端-服务器架构:
- 服务器端:持续运行,负责消息路由和广播
- 客户端:用户交互界面,连接服务器进行通信
- 通信协议:TCP(可靠连接)/UDP(无连接)
1.2 Java核心API
ServerSocket
:服务器端监听端口Socket
:客户端建立连接BufferedReader
/PrintWriter
:字符流操作
二、聊天室功能设计
2.1 功能需求
- 多客户端连接
- 实时消息广播
- 用户昵称管理
- 上下线通知
2.2 技术方案
模块 | 技术实现 |
---|---|
网络通信 | TCP Socket |
并发处理 | 多线程 |
消息协议 | 自定义简单文本格式 |
用户管理 | 线程安全集合 |
三、服务器端实现
3.1 服务器主类
public class ChatServer {
private static final int PORT = 8888;
private static Set<ClientHandler> clients = new HashSet<>();
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("服务器启动,监听端口:" + PORT);
while (true) {
Socket clientSocket = serverSocket.accept();
ClientHandler client = new ClientHandler(clientSocket);
clients.add(client);
new Thread(client).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 广播消息给所有客户端
public static void broadcast(String message) {
clients.removeIf(ClientHandler::isClosed);
for (ClientHandler client : clients) {
client.sendMessage(message);
}
}
}
3.2 客户端处理线程
class ClientHandler implements Runnable {
private Socket socket;
private PrintWriter out;
private BufferedReader in;
private String nickname;
public ClientHandler(Socket socket) throws IOException {
this.socket = socket;
this.out = new PrintWriter(socket.getOutputStream(), true);
this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.nickname = in.readLine(); // 读取昵称
ChatServer.broadcast(nickname + " 进入了聊天室");
}
@Override
public void run() {
try {
String inputLine;
while ((inputLine = in.readLine()) != null) {
ChatServer.broadcast(nickname + ": " + inputLine);
}
} catch (IOException e) {
System.out.println(nickname + " 异常断开连接");
} finally {
closeConnection();
}
}
// 关闭连接
private void closeConnection() {
try {
ChatServer.broadcast(nickname + " 离开了聊天室");
socket.close();
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMessage(String message) {
out.println(message);
}
public boolean isClosed() {
return socket.isClosed();
}
}
四、客户端实现
4.1 客户端主类
public class ChatClient {
private static final String SERVER_IP = "127.0.0.1";
private static final int SERVER_PORT = 8888;
public static void main(String[] args) {
try {
Socket socket = new Socket(SERVER_IP, SERVER_PORT);
System.out.print("请输入昵称:");
String nickname = new Scanner(System.in).nextLine();
// 发送昵称
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println(nickname);
// 启动消息接收线程
new Thread(new MessageReceiver(socket)).start();
// 处理用户输入
Scanner scanner = new Scanner(System.in);
while (true) {
String message = scanner.nextLine();
out.println(message);
}
} catch (IOException e) {
System.out.println("无法连接到服务器");
}
}
}
class MessageReceiver implements Runnable {
private Socket socket;
private BufferedReader in;
public MessageReceiver(Socket socket) throws IOException {
this.socket = socket;
this.in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
}
@Override
public void run() {
try {
String response;
while ((response = in.readLine()) != null) {
System.out.println(response);
}
} catch (IOException e) {
System.out.println("与服务器断开连接");
}
}
}
五、运行测试
5.1 启动服务器
$ java ChatServer
服务器启动,监听端口:8888
5.2 启动多个客户端
客户端1:
请输入昵称:Alice
欢迎进入聊天室!
Alice: 大家好!
客户端2:
请输入昵称:Bob
Alice 进入了聊天室
Bob: 你好!