錯誤堆疊
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read...
at Server.receive(Server.java:34) // while((str=reader.readLine()).length()>0)
雙重錯誤
- 客戶端未正確關閉:寫入後未 `writer.close()`、`socket.close()`,導致服務端讀到 RST 包拋 `Connection reset`。
修正:
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("我是");
writer.newLine();
writer.flush();
writer.close(); // 關閉流 → 發送 FIN
socket.close(); // 關閉 Socket
- 服務端 readLine 判斷錯誤:`readLine()` 返回 `null` 表示流結束,**不返回空字符串**。
錯誤:`while((str=reader.readLine()).length()>0)` → `str` 為 `null` 拋 `NullPointerException`,或流異常中斷。
修正:
String str;
while ((str = reader.readLine()) != null) { // 判斷 null
if (str.length() == 0) break; // 可選:空行作為消息邊界
msg.append(str).append("\r\n");
}
瀏覽器訪問不報錯原因
- 瀏覽器發送完整 HTTP 請求,**正確發送 `Connection: close` / `Content-Length` / Chunked 編碼**,並**主動關閉連接**(發送 FIN),服務端正常讀到 `null` 結束循環。
最佳實踐
- **客戶端**:`try-with-resources` 自動關閉 `Socket`、`Writer`。
- **服務端**:`readLine() != null` 循環,業務協議定義消息邊界(空行、長度前綴、特定分隔符)。
- **資源釋放習慣**:`finally` 或 `try-with-resources` 確保 `close()`。