
java服务器在处理完一个客户端请求后会退出,是因为当前代码只接受一次连接并读取数据;要实现持续服务,需将接受连接和处理逻辑放入无限循环中,并为每个连接启用独立线程。
你的 Java 服务器当前使用了 try-with-resources 语句包裹 ServerSocket 和首个 Socket,这导致整个资源生命周期仅覆盖单次连接——一旦客户端关闭连接(如 Go 客户端调用 conn.Close()),in.readLine() 返回 null,循环结束,try 块退出,ServerSocket 也被自动关闭,进程随之终止。
✅ 正确做法是:将 serverSocket.accept() 放入外层无限循环,每次接受新连接后,在新线程中处理该连接,从而保证服务器长期运行、并发响应多个客户端。
以下是改进后的 Java 服务器示例(含异常处理与资源管理):
import java.io.*;
import java.net.*;
public class EchoServer {
public static void main(String[] args) {
int port = 4444;
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Echo server started on port " + port);
// 持续等待并接受新连接
while (!Thread.currentThread().isInterrupted()) {
Socket clientSocket = serverSocket.accept();
System.out.println("New client connected: " + clientSocket.getRemoteSocketAddress());
// 为每个客户端启动独立线程处理
new Thread(() -> handleClient(clientSocket)).start();
}
} catch (IOException e) {
System.err.println("Server error: " + e.getMessage());
e.printStackTrace();
}
}
private static void handleClient(Socket clientSocket) {
try (
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)
) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Received: " + inputLine);
out.println(inputLine); // 回显
}
} catch (IOException e) {
System.err.println("Client handler error: " + e.getMessage());
} finally {
try {
clientSocket.close();
System.out.println("Client connection closed.");
} catch (IOException ignored) {}
}
}
}⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 不要在主线程中直接 readLine() 后阻塞——这会串行化所有请求;务必用多线程(或更优方案如 NIO/Netty)实现并发;
- ServerSocket 必须在 while 循环外初始化并保持打开状态,否则每次循环都会尝试绑定已占用端口,抛出 BindException;
- Go 客户端目前未换行(\n),而 readLine() 依赖换行符终止读取——请修改客户端发送带换行的数据:
func main() {
fmt.Println("start client")
conn, err := net.Dial("tcp", "localhost:4444")
if err != nil {
log.Fatal("Connection error:", err)
}
defer conn.Close()
// ✅ 关键:发送带 \n 的字符串,使 readLine() 正常返回
_, _ = conn.Write([]byte("hello world\n"))
// 可选:读取服务器回显(验证通信)
buf := make([]byte, 128)
n, _ := conn.Read(buf)
fmt.Println("Server replied:", string(buf[:n]))
fmt.Println("done")
}? 总结:服务器“不终止”的本质是保持 ServerSocket 活跃并持续调用 accept();而“支持多请求”则依赖于连接处理逻辑与主监听循环解耦——推荐始终采用“主线程 accept + 工作线程 handle”模式,这是构建健壮 TCP 服务器的基础范式。










