Java NIO (New I/O) 自 JDK 1.4 引入,透過 Channel、Buffer、Selector 等核心元件,支援非阻塞式 I/O,能顯著提升高併發網路應用的效能。本文提供一個完整的 Client/Server 範例,示範如何使用 NIO 進行物件序列化傳輸。
public class SerializableUtil {
public static byte[] toBytes(Object object) { /* 省略:使用 ByteArrayOutputStream + ObjectOutputStream */ }
public static Object toObject(byte[] bytes) { /* 省略:使用 ByteArrayInputStream + ObjectInputStream */ }
}
public class MyRequestObject implements Serializable { /* name, value, bytes 欄位 */ }
public class MyResponseObject implements Serializable { /* name, value, bytes 欄位 */ }
Server 建立 ServerSocketChannel 設為非阻塞,註冊 OP_ACCEPT 到 Selector。事件迴圈中處理新連線,並為每個 SocketChannel 讀取完整資料流,反序列化為 MyRequestObject,處理後回傳 MyResponseObject。
// 關鍵片段
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(10000));
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (selector.select() > 0) {
Iterator it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = it.next(); it.remove();
if (key.isAcceptable()) { /* accept 新連線 */ }
else if (key.isReadable()) { /* 讀取資料 */ }
}
}
Client 啟動 100 條執行緒並發連線測試。每個執行緒建立 SocketChannel 連線,發送請求物件,關閉輸出流 (shutdownOutput) 告知 Server 訊息結束,然後讀取回應。
// Client 執行緒片段
socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("localhost", 10000));
sendData(socketChannel, requestObj); // 內部 write + shutdownOutput
MyResponseObject resp = receiveData(socketChannel); // 讀取直到 -1
socketChannel.socket().shutdownInput();
MyServer3.main。MyClient3.main。此範例展示了 NIO 非阻塞模型下,單執行緒處理多連線的基本架構,適合作為高效能網路程式的起點。