tcp echo 通信中 java 服务器无法回传消息的常见原因是 go 客户端向 java 服务器发送消息后阻塞在读取阶段,根本原因是 java 服务端使用 bufferedreader.readline() 等待换行符(\n 或 \r\n)作为输入终止标志,而 go 客户端未发送换行符,导致服务端始终阻塞在 readline() 调用中。
Java 的 BufferedReader.readLine() 是行缓冲读取方法,它会持续从输入流中读取字节,直到遇到换行符(\n、\r\n 或 \r)才返回当前行内容;若未收到换行符,则该方法将一直阻塞。而你的 Go 客户端代码中:
strEcho := "Hello" _, err = conn.Write([]byte(strEcho)) // ❌ 未包含换行符
仅发送了 "Hello" 字节序列(即 ['H','e','l','l','o']),没有 \n,因此 Java 服务端的 in.readLine() 永远不会返回,后续的 out.println(s) 也就不会执行——这正是客户端卡在 conn.Read() 前、看似“写成功但无响应”的根本原因。
✅ 正确做法是:确保 Go 客户端发送带换行符的字符串,与服务端 readLine() 行为严格匹配:
strEcho := "Hello\n" // ✅ 显式添加 '\n' // 或更健壮地使用 fmt.Fprintln: // import "fmt" // _, err = fmt.Fprintf(conn, "Hello\n")
同时,为提升健壮性,建议对 Java 服务端做两点优化:
添加超时机制,避免单个异常连接长期占用线程:
clientSocket.setSoTimeout(30000); // 30秒读超时
显式刷新输出流(虽然 PrintWriter 构造时设 autoFlush=true 已覆盖此需求,但仍建议理解原理):
out.println(s); // 自动 flush(因构造时传入 true) // 等价于:out.print(s + "\n"); out.flush();
⚠️ 注意事项:

总结:TCP 文本协议通信必须保证收发两端的换行约定一致。readLine() ≠ “读任意字节”,而是“读一行”。修复只需一行改动——在 Go 客户端发送字符串末尾添加 \n,即可让 Java 服务端顺利解包、回显并返回,完成标准 Echo 流程。