資料交換完成後,正確關閉連接至關重要。本文實測驗證關閉 Socket 與 ServerSocket 的差異,揭示客戶端感知狀態(isConnected、isClosed、read() 回傳值)與例外拋出時機。
// 伺服器:接受連接後立即關閉 Socket
ServerSocket serverSocket = new ServerSocket(1234);
while (true) {
Socket socket = serverSocket.accept();
socket.close();
}
// 客戶端:連接後睡 1 秒再讀取
Socket socket = new Socket("127.0.0.1", 1234);
Thread.sleep(1000);
System.out.println("read() = " + socket.getInputStream().read()); // -1
System.out.println("isConnected() = " + socket.isConnected()); // true
System.out.println("isClosed() = " + socket.isClosed()); // false
Socket 後,客戶端 read() 回傳 -1(非阻塞),但 isConnected()=true、isClosed()=false —— 客戶端不會立即感知連接關閉。write(),將拋出 SocketException。ServerSocket(而非 Socket),客戶端 read() 拋出 SocketException: Connection reset。if (serverSocket.isBound() && !serverSocket.isClosed())
System.out.println("活動狀態");
else
System.out.println("非活動狀態");
註:close() 不會改變 isBound()(仍為 true),類似 Socket.isConnected() 行為。
關閉 Socket 只是結束雙向資料流,連接物件狀態標記不變;關閉 ServerSocket 才真正釋放端口。開發者應依業務需求決定關閉層級,並正確解讀 read()=-1 與例外的語意差異。