Board logo

标题: 绑定端口并向Selector注册accept事件 4 [打印本页]

作者: look_w    时间: 2019-4-12 16:54     标题: 绑定端口并向Selector注册accept事件 4

回过神来我们接着找unsalf的初始化实例。继续往上查看的构造方法,调用了抽象方法newUnsafe,NioServerSocketChannel继承了NioSocketChannle,最终发现unsafe其实是NioSocketChannelUnsafe

    protected AbstractChannel(Channel parent) {
            this.parent = parent;
            id = newId();
            unsafe = newUnsafe();
            pipeline = newChannelPipeline();
        }

11623065-b89e6b0fd4b76053.png

    @Override
        protected AbstractNioUnsafe newUnsafe() {
            return new NioSocketChannelUnsafe();
        }

进入查看其bind(),该方法在其父类AbstractChannel.AbstractUnsafe#bind()中

            @Override
            public final void bind(final SocketAddress localAddress, final ChannelPromise promise) {
               
                //省略代码
               
                //未绑定之前:未激活状态
                boolean wasActive = isActive();
                try {
                    //进行绑定,成功后激活状态
                    doBind(localAddress);
                } catch (Throwable t) {
                    safeSetFailure(promise, t);
                    closeIfClosed();
                    return;
                }
               
                //判断是哦付激活来进行 Event传播:ChannelActive
                if (!wasActive && isActive()) {
                    invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            pipeline.fireChannelActive();
                        }
                    });
                }
     
                safeSetSuccess(promise);
            }

这里有两个地方指的继续深入查看其源码,一个是doBind()绑定端口,另一个是fireChannelActive()传播事件,我们当前的节点是在pipleline头部 HeadContext里面。

    doBind()最终进入NioServerSocketChannel#doBind()调用了jdk底层的端口绑定方法。完成了绑定。

    @Override
        protected void doBind(SocketAddress localAddress) throws Exception {
            if (PlatformDependent.javaVersion() >= 7) {
                javaChannel().bind(localAddress, config.getBacklog());
            } else {
                javaChannel().socket().bind(localAddress, config.getBacklog());
            }
        }

    进入DefaultChannelPipeline.HeadContext#channelActive()发现调用了readIfIsAutoRead()

    @Override
            public void channelActive(ChannelHandlerContext ctx) throws Exception {
                ctx.fireChannelActive();
     
                readIfIsAutoRead();
            }




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0