本文目录导读:

我来详细介绍如何使用Java Socket编程实现一个简单的聊天程序,包括服务端和客户端。
项目结构
chat-app/
├── Server.java # 服务端
├── Client.java # 客户端
└── ClientHandler.java # 客户端处理线程
服务端实现
import java.io.*;
import java.net.*;
import java.util.*;
public class Server {
private static Set<ClientHandler> clients = Collections.synchronizedSet(new HashSet<>());
public static void main(String[] args) {
int port = 8888;
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("聊天服务器启动,监听端口: " + port);
while (true) {
// 接受客户端连接
Socket socket = serverSocket.accept();
System.out.println("新客户端连接: " + socket.getRemoteSocketAddress());
// 为每个客户端创建处理线程
ClientHandler clientHandler = new ClientHandler(socket);
clients.add(clientHandler);
new Thread(clientHandler).start();
}
} catch (IOException e) {
System.err.println("服务器异常: " + e.getMessage());
}
}
// 广播消息给所有客户端
public static void broadcast(String message, ClientHandler sender) {
synchronized (clients) {
for (ClientHandler client : clients) {
// 发送给除了发送者以外的所有客户端
if (client != sender) {
client.sendMessage(message);
}
}
}
}
// 移除客户端
public static void removeClient(ClientHandler client) {
clients.remove(client);
System.out.println("客户端断开连接,当前在线人数: " + clients.size());
}
}
客户端处理线程
import java.io.*;
import java.net.*;
public class ClientHandler implements Runnable {
private Socket socket;
private BufferedReader reader;
private PrintWriter writer;
private String username;
public ClientHandler(Socket socket) {
this.socket = socket;
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
System.err.println("初始化客户端处理器失败: " + e.getMessage());
}
}
@Override
public void run() {
try {
// 获取用户名
writer.println("请输入您的用户名:");
this.username = reader.readLine();
// 发送欢迎消息
String welcomeMsg = username + " 加入了聊天室";
System.out.println(welcomeMsg);
Server.broadcast(welcomeMsg, this);
// 处理客户端消息
String message;
while ((message = reader.readLine()) != null) {
if (message.equalsIgnoreCase("/quit")) {
break;
} else if (message.equalsIgnoreCase("/help")) {
writer.println("可用命令:");
writer.println("/quit - 退出聊天室");
writer.println("/users - 查看在线用户");
writer.println("/help - 查看帮助");
} else if (message.equalsIgnoreCase("/users")) {
// 这个功能留给读者实现
writer.println("此功能待实现");
} else {
// 广播消息
String formattedMessage = "[" + username + "]: " + message;
System.out.println(formattedMessage);
Server.broadcast(formattedMessage, this);
}
}
} catch (IOException e) {
System.err.println("客户端处理异常: " + e.getMessage());
} finally {
// 客户端断开连接
String leaveMsg = username + " 离开了聊天室";
Server.broadcast(leaveMsg, this);
Server.removeClient(this);
closeConnection();
}
}
public void sendMessage(String message) {
if (writer != null) {
writer.println(message);
}
}
private void closeConnection() {
try {
if (reader != null) reader.close();
if (writer != null) writer.close();
if (socket != null) socket.close();
} catch (IOException e) {
System.err.println("关闭连接异常: " + e.getMessage());
}
}
}
客户端实现
import java.io.*;
import java.net.*;
public class Client {
private Socket socket;
private BufferedReader reader;
private PrintWriter writer;
public static void main(String[] args) {
new Client().start();
}
public void start() {
try {
// 连接到服务器
socket = new Socket("localhost", 8888);
System.out.println("已连接到聊天服务器");
// 初始化读写流
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(), true);
// 启动接收消息的线程
new Thread(new MessageReceiver()).start();
// 处理用户输入
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
String userInput;
while ((userInput = consoleReader.readLine()) != null) {
writer.println(userInput);
if (userInput.equalsIgnoreCase("/quit")) {
break;
}
}
} catch (IOException e) {
System.err.println("客户端异常: " + e.getMessage());
} finally {
closeConnection();
}
}
// 接收服务器消息的线程
private class MessageReceiver implements Runnable {
@Override
public void run() {
try {
String message;
while ((message = reader.readLine()) != null) {
System.out.println(message);
}
} catch (IOException e) {
// 连接断开时退出
System.out.println("与服务器的连接已断开");
} finally {
closeConnection();
System.exit(0);
}
}
}
private void closeConnection() {
try {
if (reader != null) reader.close();
if (writer != null) writer.close();
if (socket != null) socket.close();
} catch (IOException e) {
System.err.println("关闭连接异常: " + e.getMessage());
}
}
}
运行说明
-
编译所有Java文件:
javac Server.java ClientHandler.java Client.java
-
首先启动服务端:
java Server
-
启动多个客户端(在不同终端窗口):
java Client
程序特点
- 多线程处理:支持多个客户端同时连接
- 消息广播:消息会发送给所有在线用户
- 用户管理:自动处理用户上下线
- 命令系统:支持简单的命令(/quit, /help等)
- 异常处理:完善的连接管理和异常处理
扩展建议
- 实现私聊功能:添加
/msg [username] [message]命令 - 用户列表:实现
/users命令显示在线用户 - 消息加密:使用SSL/TLS加密通信
- 图形界面:使用JavaFX或Swing开发GUI
- 消息持久化:将聊天记录存储到数据库
- 文件传输:支持发送图片和文件
这个简单的聊天程序展示了Java Socket编程的核心概念,包括TCP连接、多线程处理和输入输出流操作,你可以根据需要对其进行扩展和完善。