Board logo

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

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

上一节我们分析了注册Selector的过程,其中关键代码是AbstractNioChannel#doRegister()中的一段。其中第二个参数是0表示未Selector注册事件。

                    // 注册到java的Selector,未绑定事件,并且获得selectionKey
                    selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);

本节我们查看端口绑定并且分析Selector绑定accept事件的过程。

回到入口代码ChannelFuture future = serverBootstrap.bind(PORT).sync();往下走,来到AbstractBootstrap#doBind,

     private ChannelFuture doBind(final SocketAddress localAddress) {
            //初始化并注册
            final ChannelFuture regFuture = initAndRegister();
            final Channel channel = regFuture.channel();
            if (regFuture.cause() != null) {
                return regFuture;
            }
     
            if (regFuture.isDone()) {
         
                ChannelPromise promise = channel.newPromise();
                // 绑定端口
                doBind0(regFuture, channel, localAddress, promise);
                return promise;
            } else {
                final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);
                regFuture.addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        Throwable cause = future.cause();
                        if (cause != null) {
                        
                            promise.setFailure(cause);
                        } else {
                           
                            promise.registered();
     
                            doBind0(regFuture, channel, localAddress, promise);
                        }
                    }
                });
                return promise;
            }
        }

进入doBind0()

     private static void doBind0(
                final ChannelFuture regFuture, final Channel channel,
                final SocketAddress localAddress, final ChannelPromise promise) {
     
            channel.eventLoop().execute(new Runnable() {
                @Override
                public void run() {
                    if (regFuture.isSuccess()) {
                        // 绑定端口
                        channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
                    } else {
                        promise.setFailure(regFuture.cause());
                    }
                }
            });
        }

由于channel变量其实是NioServerSocketChannel实例。因此我们进入其父类AbstractChannel





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