public void testScannerServer() throws IOException {
System.out.println("服务端开启");
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 非阻塞
serverSocketChannel.configureBlocking(false);
serverSocketChannel.bind(new InetSocketAddress(8092));
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (selector.select() > 0) {
// it won't clear the existing items 不会清空已经存在的 selectionKey。因此遍历处理一个后需要remove移除
Iterator it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
// 为什么要remove?因为 select 就绪队列,如果不移除就会一直存在
// https://stackoverflow.com/questions/7132057/why-the-key-should-be-removed-in-selector-selectedkeys-iterator-in-java-ni
it.remove();
if (!key.isValid()) {
System.out.println("连接不可用");
} else if (key.isAcceptable()) {
// 新连接
System.out.println("服务端接受到新连接");
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false); // 非阻塞
socketChannel.register(selector, SelectionKey.OP_READ); // 注册可读事件
} else if (key.isReadable()) {
// 有客户端发送数据
SocketChannel socketChannel = (SocketChannel) key.channel();
// 开始读取数据
System.out.println(new Date().toString());
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
if (socketChannel.read(byteBuffer) == -1) {
// -1 说明客户端关闭了写或者直接close
System.out.println("客户端关闭连接");
// socketChannel.close(); // 其实不需要调用,因为客户端已经关闭, 为了程序稳健性可以开启
key.cancel(); // 取消注册
} else {
byteBuffer.flip();
System.out.println(new String(byteBuffer.array(), 0, byteBuffer.limit()));
byteBuffer.clear();
}
}
}
}
}