3-2-1 NioServerSocketChannel 的创建

Posted programmLover

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3-2-1 NioServerSocketChannel 的创建相关的知识,希望对你有一定的参考价值。

一 NioserverSocketChannel 创建时机:

  NioServerSocketChannel 会在 AbstractBootstrap#bind(int) 绑定端口时调用到 AbstractBootstrap.initAndRegister()  方法创建 ChannelFuture,调用 ChannelFactory.newChannel(),通过反射来创建 NioServerSocketChannel 实例。

 

二 服务端 Channel 创建流程

 1. 进入 NioServerSocketChannel 默认构造方法,查看 NioServerSocketChannel 创建流程

    /**
     * Create a new instance
     */
    public NioServerSocketChannel() {
        this(newSocket(DEFAULT_SELECTOR_PROVIDER));
    }

 NioServerSocketChannel() 会先调用 NioServerSocketChannel#newSocket 创建一个 Nio 的 ServerSocketChannel 实例,然后继续调用重载的构造方法

  

 继续跟进到 NioServerSocketChannel(ServerSocketChannel channel)

    /**
     * Create a new instance using the given {@link ServerSocketChannel}.
     */
    public NioServerSocketChannel(ServerSocketChannel channel) {
        super(null, channel, SelectionKey.OP_ACCEPT);
        config = new NioServerSocketChannelConfig(this, javaChannel().socket());
    }

  NioServerSocketChannel(ServerSocketChannel channel) 调用父类的构造方法 AbstractNioMessageChannel#bstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp), 然后 创建一个 NioServerSocketChannelConfig 实例并保存

 

 继续跟进 AbstractNioMessageChannel#bstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp)

    protected AbstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
        super(parent, ch, readInterestOp);
    }

 又是父类的 构造方法,再跟进到 AbstractNioChannel#AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp)

    /**
     * Create a new instance
     *
     * @param parent            the parent {@link Channel} by which this instance was created. May be {@code null}
     * @param ch                the underlying {@link SelectableChannel} on which it operates
     * @param readInterestOp    the ops to set to receive data from the {@link SelectableChannel}
     */
    protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
        super(parent);
        //保存 Nio 的 SocketChannel, readInterestOp
        this.ch = ch;
        this.readInterestOp = readInterestOp;
        try {
            //配置为 非阻塞模式
            ch.configureBlocking(false);
        } catch (IOException e) {
            try {
                ch.close();
            } catch (IOException e2) {
                logger.warn(
                            "Failed to close a partially initialized socket.", e2);
            }

            throw new ChannelException("Failed to enter non-blocking mode.", e);
        }
    }

  AbstractNioChannel#AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) 先继续调用父类构造方法 AbstractChannel#AbstractChannel(Channel parent),然后保存 Nio 的 SocketChannel, readInterestOp,从上一步方法我们得知,这里传入的 readInterestOp 应为SelectionKey.OP_READ,再配置为非阻塞模式

 

 继续跟进到  AbstractChannel#AbstractChannel(Channel parent)

    /**
     * Creates a new instance.
     *
     * @param parent
     *        the parent of this channel. {@code null} if there\'s no parent.
     */
    protected AbstractChannel(Channel parent) {
        //设置parent
        this.parent = parent;
        //创建并设置 ChannelId、Unsafe、DefaultChannelPipeline
        id = newId();
        unsafe = newUnsafe();
        pipeline = newChannelPipeline();
    }

 AbstractChannel#AbstractChannel(Channel parent) 先设置parent,这里传入的parent 为 null, 然后创建 id,unsafe ,pipeline 并保存,unsafe 会根据不同的 Channel 创建不同的 Unsafe,通常服务端会创建 NioServerSocketChannel,创建的 unsafe 类型为 NioMessageUnsafe,客户端会创建 NioSocketChannel, 创建的 unsafe 类型为 NioByteUnsafe, pipeline 类型为 DefaultChannelPipeline

 

 进入 NioServerSocketChannelConfig(NioServerSocketChannel channel, ServerSocket javaSocket) 构造方法,查看 config 创建实例流程

        private NioServerSocketChannelConfig(NioServerSocketChannel channel, ServerSocket javaSocket) {
            super(channel, javaSocket);
        }

 调用父类方法,继续跟进

 

 进入 DefaultServerSocketChannelConfig(ServerSocketChannel channel, ServerSocket javaSocket) 构造方法

    /**
     * Creates a new instance.
     */
    public DefaultServerSocketChannelConfig(ServerSocketChannel channel, ServerSocket javaSocket) {
        super(channel);
        this.javaSocket = ObjectUtil.checkNotNull(javaSocket, "javaSocket");
    }

 DefaultServerSocketChannelConfig(ServerSocketChannel channel, ServerSocket javaSocket) 构造方法继续调用父类构造器传入 ServerSocketChannel,然后保存 jdk 的 ServerSocket

 

 进入 DefaultChannelConfig(Channel channel)

    public DefaultChannelConfig(Channel channel) {
        this(channel, new AdaptiveRecvByteBufAllocator());
    }

 DefaultChannelConfig(Channel channel) 会先创建一个 AdaptiveRecvByteBufAllocator 实例,然后继续调用构造方法

 

 进入 DefaultChannelConfig(Channel channel, RecvByteBufAllocator allocator)

    protected DefaultChannelConfig(Channel channel, RecvByteBufAllocator allocator) {
        setRecvByteBufAllocator(allocator, channel.metadata());
        this.channel = channel;
    }

 

  DefaultChannelConfig(Channel channel, RecvByteBufAllocator allocator) 保存 channel 和 RecvByteBufAllocator 

 

 

至此 NioServerSocketChannel 创建完成

以上是关于3-2-1 NioServerSocketChannel 的创建的主要内容,如果未能解决你的问题,请参考以下文章

2021-08-26:长度为N的数组arr,一定可以组成N^2个数字对。例如arr = [3,1,2],数字对有(3,3) (3,1) (3,2) (1,3) (1,1) (1,2) (2,3) (2

生成所有可能的独特选择组合

书籍-算法

求1!+2!+3!+....20!的值

多目标跟踪:文献综述

十大排序之归并排序