SocketChannel、ServerSocketChannel、DatagramChannel。ServerSocketChannel 僅監聽連接,不傳輸數據。


ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.bind(new InetSocketAddress("localhost", 8888));
ssc.configureBlocking(false);
Selector selector = Selector.open();
ssc.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
if (selector.select() == 0) continue;
for (SelectionKey key : selector.selectedKeys()) {
if (key.isAcceptable()) {
SocketChannel sc = ((ServerSocketChannel)key.channel()).accept();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer buf = ByteBuffer.allocate(4096);
StringBuilder sb = new StringBuilder();
while (sc.read(buf) > 0) {
buf.flip(); sb.append(new String(buf.array())); buf.clear();
}
System.out.println("recv: " + sb);
key.interestOps(SelectionKey.OP_WRITE);
} else if (key.isWritable()) {
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer buf = ByteBuffer.wrap(("server: " + Math.random()).getBytes());
while (buf.hasRemaining()) sc.write(buf);
key.interestOps(SelectionKey.OP_READ);
}
selector.selectedKeys().remove(key);
}
}
SelectionKey 非線程安全,需同步或單線程操作註冊/取消。// 主循環中
if (key.isReadable()) {
readPool.execute(new ReadTask((SocketChannel)key.channel()));
key.interestOps(SelectionKey.OP_WRITE);
} else if (key.isWritable()) {
writePool.execute(new WriteTask((SocketChannel)key.channel()));
key.interestOps(SelectionKey.OP_READ);
}
完整代碼見原文,包含 ReadTask/WriteTask 實現。
wakeup() 喚醒阻塞的 select()。key.attach(obj) 傳遞上下文。key.cancel(),通道關閉自動取消。ByteBuffer.allocateDirect)。