雖然生產環境多採用 Netty、Mina、gRPC 等高階框架,但理解原生 java.net.Socket 阻塞 I/O 模型是網路編程基石。本文提供最精簡的單線程 Server/Client 雙向通訊範例,涵蓋連線建立、行訊息收發、優雅關閉。
ServerSocket.accept() 阻塞等待單一連線 → 輸入/輸出流包裝 → 迴圈 readLine() / println() → 收到 "bye" 斷開。new Socket(host, port) 連線 → 標準輸入 System.in 讀取使用者輸入 → 發送至 Server → 讀取 Server 回應 → 輸入 "bye" 結束。Client 端代碼
關鍵技術細節
| 細節 | 說明 | 注意事項 |
|---|---|---|
try-with-resources | JDK 7+ 自動關閉 Socket/Stream,防洩漏 | 單線程模式下簡單可靠 |
PrintWriter(..., true) | 啟用 autoFlush,println 立即發送 | 否則需手動 flush() |
| 指定 Charset (UTF-8) | 避免平台預設編碼不一致導致亂碼 | 雙端必須一致 |
readLine() 阻塞 | 遇到 \n, \r\n, EOF 返回 | 客戶端需換行送出 |
| 單線程限制 | 同一時間只能服務一個 Client | 生產需多線程/IO 多路復用 |
SimpleServer,控制台顯示「Server 啟動,監聽 10000...」SimpleClient,顯示「已連線至 Server」Hello Socket → Enter收到: Hello SocketServer 回應: Server Echo: Hello Socketbye → 雙向關閉while(true) { new Thread(new Handler(server.accept())).start(); }ServerSocketChannel + Selector 單線程處理萬級連線。socket.shutdownOutput() 發送 FIN,對端讀到 -1/EOF,再關閉輸入。原生 Socket 阻塞 I/O 模型代碼簡潔、語義清晰,適合學習網路分層 (傳輸層/應用層協議)、流操作、同步阻塞語義。實務開發中,除極簡單工具/測試外,建議直接採用 Netty 等成熟框架,專注業務邏輯而非底層連線管理。