客戶端發送消息,服務端收到並打印,但雙方控制台均無後續輸出,程序卡住不退出。
int len = -1 初始化錯誤// 錯誤代碼片段
char[] c = new char[2];
int len = -1; // ★ 錯誤在此
while ((len = br.read(c)) != -1) {
sb.append(c, 0, len);
}
BufferedReader.read(char[]) 返回 實際讀取的字符數,正常情況 ≥ 0。初始化為 -1 無實質危害,但**真正問題在於協議不匹配**:
PrintStream.println() 發送帶 \n 的行文本read(char[]) 按字符數組讀,**不識別行結束符**,會阻塞等待填滿數組或流關閉BufferedReader.readLine()// 服務端接收循環
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
String line;
while ((line = br.readLine()) != null) { // 遇到 \n 返回行內容(不含換行符)
System.out.println("收到: " + line);
// 業務處理...
}
PrintWriter + autoFlush=truePrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream(), "UTF-8"), true);
pw.println("消息內容"); // 自動發送 + 換行符觸發對端 readLine 返回
// 客戶端
Socket s = new Socket("127.0.0.1", 8888);
try (PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream(), "UTF-8"), true);
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
BufferedReader console = new BufferedReader(new InputStreamReader(System.in))) {
String input;
while ((input = console.readLine()) != null) {
pw.println(input); // 發送
String reply = br.readLine(); // 接收回显
System.out.println("Server: " + reply);
}
}
// 服務端
ServerSocket ss = new ServerSocket(8888);
while (true) {
Socket s = ss.accept();
new Thread(() -> {
try (BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream(), "UTF-8"), true)) {
String msg;
while ((msg = br.readLine()) != null) {
System.out.println("Client: " + msg);
pw.println("Echo: " + msg);
}
} catch (IOException e) { e.printStackTrace(); }
}).start();
}
| API | 行為 | 適用場景 |
|---|---|---|
read(char[]) | 按字符數讀取,不識別行結束 | 二進制協議/固定長度 |
readLine() | 讀取一行 (以 \n/\r\n 結尾) | 文本行協議 (最常用) |
PrintWriter.println() | 發送字符串 + \n,可配置 autoFlush | 文本發送 |
「發送端 println ↔ 接收端 readLine」是文本 Socket 通信的黃金搭檔,拒絕手動拼裝字符數組與判斷 -1。