Netty4源码分析—ServerSocketChannel注册到Selector_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Netty4源码分析—ServerSocketChannel注册到Selector

Netty4源码分析—ServerSocketChannel注册到Selector

 2013/11/14 12:50:01  bzhjian  程序员俱乐部  我要评论(0)
  • 摘要:一、生成serversocketchannelServerBootstrap设置channel类型bootstrap.channel(NioServerSocketChannel.class)时,ServerBootstrap的父类AbstractBootstrap的初始ChannelFactory的对象,ChannelFactory的作用是生成ServerSocketChannel对象,channel方法代码:publicBchannel(Class<?extendsC>
  • 标签:Server 源码 net 分析 CTO socket

class="MsoNormal" style="text-align: left;">一、生成serversocketchannel

?

???? ServerBootstrap设置channel类型?bootstrap.channel(NioServerSocketChannel.class)时,ServerBootstrap的父类AbstractBootstrap的初始ChannelFactory的对象,ChannelFactory的作用是生成ServerSocketChannel对象,channel方法代码:

?

public B channel(Class<? extends C> channelClass) {
        if (channelClass == null) {
            throw new NullPointerException("channelClass");
        }
        return channelFactory(new BootstrapChannelFactory<C>(channelClass));
}

?

??? BootstrapChannelFactoryAbstractBootstrap的内部类。

?

二、将serverchannel注册到selector

?

? ServerBootstrap在绑定端口(bootstrap.bind(8080))时,调用AbstractBootstrapinitAndRegister方法:

final ChannelFuture initAndRegister() {
        final Channel channel = channelFactory().newChannel();//(1)
        try {
            init(channel);//(2)
        } catch (Throwable t) {
            channel.unsafe().closeForcibly();
            return channel.newFailedFuture(t);
        }

        ChannelPromise regPromise = channel.newPromise();//(3)
        group().register(channel, regPromise);//(4)
        if (regPromise.cause() != null) {
            if (channel.isRegistered()) {
                channel.close();
            } else {
                channel.unsafe().closeForcibly();
            }
        }

        return regPromise;
    }

????? 1、调用ChannelFactory对象生成ServerBootstrap channel(Class<? extends C> channelClass)方法中设置的channelClass对象即NioServerSocketChannel对象,也就是Netty重新封装过的ServerSocketChannel对象,至于Netty为什么要封装ServerSocketChannel后面章节再写。

?? ?? 2、 初化NioServerSocketChannel对象,将我们在创建ServerBootstrap对象中设置的option attr值设置到NioServerSocketChannel对象中的configarrs属性中。

????? 3、生成ChannelPromise对象,这个对象主要是对channel的注册状态进行监听

????? 4、 eventLoop设置到channel中,并调用AbstractChannel$AbstractUnsaferegister0方法奖channel注册到eventLoop中的selector,并将ChannelPromise状态设置为成功:

private void register0(ChannelPromise promise) {
            try {
                // check if the channel is still open as it could be closed in the mean time when the register
                // call was outside of the eventLoop
                if (!ensureOpen(promise)) {
                    return;
                }
                doRegister();     //将serverchannel注册到selector中
                registered = true;
                promise.setSuccess();
                pipeline.fireChannelRegistered();
                if (isActive()) {
                    pipeline.fireChannelActive();
                }
            } catch (Throwable t) {
                // Close the channel directly to avoid FD leak.
                closeForcibly();
                closeFuture.setClosed();
                if (!promise.tryFailure(t)) {
                    logger.warn(
                            "Tried to fail the registration promise, but it is complete already. " +
                                    "Swallowing the cause of the registration failure:", t);
                }
            }
       }

?

三、绑定端口

? 通过initAndRegister方法serverchannel注册到selector后调用doBind0方法注册端口

private static void doBind0(
            final ChannelFuture regFuture, final Channel channel,
            final SocketAddress localAddress, final ChannelPromise promise) {

        // This method is invoked before channelRegistered() is triggered.  Give user handlers a chance to set up
        // the pipeline in its channelRegistered() implementation.

        channel.eventLoop().execute(new Runnable() { //(1)
            @Override
            public void run() {
                if (regFuture.isSuccess()) {
                    channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
                } else {
                    promise.setFailure(regFuture.cause());
                }
            }
        });
}

?

?

?

?

?

?

发表评论
用户名: 匿名