(三)JAVA NIO SELECTOR

Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。

SelectServer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class SelectServer {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(9999));
serverSocketChannel.configureBlocking(false);
Selector selector = Selector.open();
SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
int select = selector.select();
if (select > 0) {
Iterator keyIterator = selector.selectedKeys().iterator();
while (keyIterator.hasNext()) {
SelectionKey next = (SelectionKey) keyIterator.next();
keyIterator.remove();
if (next.isAcceptable()) {
System.out.println("isAcceptable");
SocketChannel channel = ((ServerSocketChannel) next.channel()).accept();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
} else if (next.isConnectable()) {
System.out.println("connect");
} else if (next.isReadable()) {
System.out.println("isReadable");
SocketChannel socketChannel = (SocketChannel) next.channel();
ByteBuffer readByteBuffer = ByteBuffer.allocate(100);
int read = socketChannel.read(readByteBuffer);
System.out.println(new String(readByteBuffer.array(), 0, read));
socketChannel.register(selector, SelectionKey.OP_WRITE);
socketChannel.write(readByteBuffer);
} else if (next.isWritable()) {
System.out.println("isWritable");
SocketChannel socketChannel = (SocketChannel) next.channel();
socketChannel.register(selector, SelectionKey.OP_READ);
}
}
}
}
}
}

NioChannelClient.java

1
2
3
4
5
6
7
8
9
10
public class NioChannelClient {
public static void main(String[] args) throws IOException {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("localhost", 9999));
while (true) {
Scanner input = new Scanner(System.in);
socketChannel.write(ByteBuffer.wrap(input.nextLine().getBytes()));
}
}
}

Nio源码地址​github.com