From 7e048465115087ac87d5c43d8cf644891f56e34e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=A0=E7=9A=84Gitee=E7=94=A8=E6=88=B7=E5=90=8D?= <16423891+five-steps-apart@user.noreply.gitee.com> Date: Thu, 4 Dec 2025 23:49:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=201.=E4=BF=AE=E5=A4=8DclientSocket.close(?= =?UTF-8?q?)=E5=88=A0=E9=99=A4=E5=AF=BC=E8=87=B4=E7=9A=84=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E6=B3=84=E6=BC=8F=202.=E5=AE=9E=E7=8E=B0=E5=A4=9A?= =?UTF-8?q?=E6=B1=A0=203.=E6=B7=BB=E5=8A=A0=E8=BF=9E=E6=8E=A5/=E6=96=AD?= =?UTF-8?q?=E5=BC=80=E6=97=A5=E5=BF=97=204.=E6=94=AF=E6=8C=81TIME=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E8=BF=94=E5=9B=9E=E7=B3=BB=E7=BB=9F=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/echo/EchoServer.java | 78 +++++++++++++------ 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/example/echo/EchoServer.java b/src/main/java/com/example/echo/EchoServer.java index f55f684..10dc361 100644 --- a/src/main/java/com/example/echo/EchoServer.java +++ b/src/main/java/com/example/echo/EchoServer.java @@ -1,70 +1,96 @@ package com.example.echo; -import java.io.*; -import java.net.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.ServerSocket; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** - * 单客户端Echo服务器 - * 这个服务器一次只处理一个客户端连接 + * 支持多客户端的Echo服务器 + * 修复语法错误 + 实现多客户端 + 连接日志 + TIME命令 + 验证clientSocket.close()问题 */ public class EchoServer { private static final int PORT = 8888; private ServerSocket serverSocket; private boolean running = false; + // 替换单线程池为固定线程池,支持多客户端 private ExecutorService executor; public EchoServer() { - executor = Executors.newSingleThreadExecutor(); + // 核心修改:固定线程池(支持多客户端,替代单线程) + executor = Executors.newFixedThreadPool(10); } /** - * 启动服务器 + * 启动服务器(修改为循环接受多客户端连接) */ public void start() throws IOException { serverSocket = new ServerSocket(PORT); running = true; System.out.println("Echo Server已启动,监听端口: " + PORT); - // 等待客户端连接 - System.out.println("等待客户端连接..."); - Socket clientSocket = serverSocket.accept(); - System.out.println("客户端已连接: " + clientSocket.getRemoteSocketAddress()); + // 核心修改:循环接受客户端连接(支持多客户端) + while (running) { + System.out.println("等待客户端连接..."); + Socket clientSocket = serverSocket.accept(); + String clientInfo = clientSocket.getRemoteSocketAddress().toString(); + // 打印连接日志 + System.out.println(getCurrentTime() + " 客户端已连接: " + clientInfo); - handleClient(clientSocket); + // 交给线程池处理(每个客户端一个任务,非单线程阻塞) + executor.submit(() -> handleClient(clientSocket, clientInfo)); + } } /** - * 处理客户端连接 + * 处理客户端连接(新增clientInfo参数用于日志) */ - private void handleClient(Socket clientSocket) { + private void handleClient(Socket clientSocket, String clientInfo) { try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)) { String inputLine; - System.out.println("开始与客户端通信..."); + System.out.println(getCurrentTime() + " 开始与客户端通信: " + clientInfo); while ((inputLine = in.readLine()) != null) { + // 1. 识别TIME命令,返回系统时间 + if ("TIME".equalsIgnoreCase(inputLine.trim())) { + String currentTime = getCurrentTime(); + out.println("Server: " + currentTime); + System.out.println(getCurrentTime() + " 响应TIME命令给客户端: " + clientInfo); + continue; + } + + // 2. 处理断开连接命令 if ("bye".equalsIgnoreCase(inputLine.trim())) { - System.out.println("客户端请求断开连接"); + System.out.println(getCurrentTime() + " 客户端请求断开连接: " + clientInfo); + out.println("Server: 连接即将断开"); break; } - System.out.println("收到消息: " + inputLine); - // 将收到的消息回显给客户端 + // 3. 原Echo逻辑 + System.out.println(getCurrentTime() + " 收到[" + clientInfo + "]消息: " + inputLine); out.println("Echo: " + inputLine); } } catch (IOException e) { - System.err.println("处理客户端连接时发生错误: " + e.getMessage()); + System.err.println(getCurrentTime() + " 处理客户端[" + clientInfo + "]连接时发生错误: " + e.getMessage()); } finally { try { - clientSocket.close(); - System.out.println("客户端连接已关闭"); + // ********************* 验证clientSocket.close()的核心代码 ********************* + // 测试1:注释下面这行,会导致CLOSE_WAIT连接泄漏;取消注释则正常释放资源 + clientSocket.close(); + // 打印断开日志 + System.out.println(getCurrentTime() + " 客户端已断开: " + clientInfo); } catch (IOException e) { - System.err.println("关闭客户端连接时发生错误: " + e.getMessage()); + System.err.println(getCurrentTime() + " 关闭客户端连接时出错: " + e.getMessage()); } } } @@ -85,7 +111,15 @@ public class EchoServer { } catch (InterruptedException e) { executor.shutdownNow(); } - System.out.println("服务器已停止"); + System.out.println(getCurrentTime() + " 服务器已停止"); + } + + /** + * 工具方法:获取格式化的系统时间 + */ + private String getCurrentTime() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return "[" + sdf.format(new Date()) + "]"; } public static void main(String[] args) { -- Gitee