Java NIO 网络编程模型 Reactor模式讲解

Java NIO 网络编程模型中,Reactor模式是一种基于事件驱动的模式,用于处理I/O操作。该模式将I/O操作分为两个阶段:一个是I/O准备阶段,另一个是I/O操作阶段。在I/O准备阶段,Reactor会注册到I/O Selector中,然后等待I/O事件的发生。一旦I/O事件发生,Reactor就会触发相应的事件处理器,这些事件处理器会执行I/O操作阶段的处理。

Reactor模式中包含以下几个组件:

  • Reactor:它负责监听所有连接,并分发连接给相应的处理器。
  • Acceptor:它负责接受连接,并将连接注册到I/O Selector中,以便进行I/O操作。
  • Handlers:它们负责I/O操作阶段的处理。当I/O事件发生时,Reactor会选择相应的处理器来处理事件。

下面是一个简单的Java NIO网络编程模型中使用Reactor模式的示例代码:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class ReactorServer {
    public static void main(String[] args) throws IOException {
        Selector selector = Selector.open();
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(8080));
        serverSocketChannel.configureBlocking(false);
        SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        selectionKey.attach(new Acceptor(serverSocketChannel));
        while (true) {
            selector.select();
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                dispatch(key);
                iterator.remove();
            }
        }
    }

    private static void dispatch(SelectionKey key) {
        Runnable attachment = (Runnable) key.attachment();
        if (attachment != null) {
            attachment.run();
        }
    }

    static class Acceptor implements Runnable {
        private ServerSocketChannel serverSocketChannel;

        public Acceptor(ServerSocketChannel serverSocketChannel) {
            this.serverSocketChannel = serverSocketChannel;
        }

        @Override
        public void run() {
            try {
                SocketChannel socketChannel = serverSocketChannel.accept();
                if (socketChannel != null) {
                    new Handler(socketChannel);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    static class Handler implements Runnable {
        private SocketChannel socketChannel;
        private ByteBuffer input = ByteBuffer.allocate(1024);
        private ByteBuffer output = ByteBuffer.allocate(1024);

        public Handler(SocketChannel socketChannel) throws IOException {
            this.socketChannel = socketChannel;
            this.socketChannel.configureBlocking(false);
            SelectionKey selectionKey = socketChannel.register(selector, SelectionKey.OP_READ);
            selectionKey.attach(this);
        }

        @Override
        public void run() {
            try {
                input.clear();
                socketChannel.read(input);
                input.flip();
                //处理input中的数据
                output.clear();
                output.put("Hello World".getBytes());
                output.flip();
                socketChannel.write(output);
            } catch (IOException) {
                e.printStackTrace();
            }
        }
    }
}