NioServerSocketChannel的默认构造函数做了什么

154 阅读3分钟

1 NioServerSocketChannel继承体系的成员变量分析

image.png

1.1 AbstractChannel

修饰符类型字段含义
private finalChannelparent指定的是监听套接字
private finalChannelIdid标识一个具体Channel
private finalUnsafeunsafe这个接口在Channel类中,表示的一些具体的i/o操作
private finalDefaultChannelPipelinepipeline表示的是Channel的pipeline,并且这里指定了具体的ChannelPipeline的具体实现DefaultChannelPipeline
private finalVoidChannelPromiseunsafeVoidPromise未知,带着问题往下看,后面在来解答
private finalCloseFuturecloseFuture字面上是一个close的Future
private volatileSocketAddresslocalAddress表示的channel的本地ip和端口
private volatileSocketAddressremoteAddress这个字段表示的Channel的远程ip和端口,注意下:这个字段的设计netty是有问题的或者说不完美的,因为Channel接口有一个方法是:SocketAddress remoteAddress();这个方法很明显只是对于那种面向连接的协议比如说TCP它才有意义,对于UDP来说这个方法没有意义,但是Channel这个接口的设计表示是通信通道,Channel这个概念还没有涉及到使用什么协议,因为Channel再往下的继承体系里面,出现了具体的协议比如是TCP还是UDP,DiagramChannel表示的就是UDP的Channel,SocketChannel和ServerSocketChannel表示的是TCP协议的Channel
private volatileEventLoopeventLoop表示的线程池的概念
private volatilebooleanregistered是否注册到i/o多路复用
privatebooleancloseInitiated未知,带着问题往下看,后面在来解答
privateThrowableinitialCloseCause未知,带着问题往下看,后面在来解答
privatebooleanstrValActive未知,带着问题往下看,后面在来解答
privateStringstrVal未知,带着问题往下看,后面在来解答

1.2 AbstractNioChannel

修饰符类型字段默认值含义
private finalSelectableChannelch这个是jdk的nio中的概念,表示是可以做多路复用的Channel
protected finalintreadInterestOp感兴趣的读事件是哪些
volatileSelectionKeyselectionKeyjdk nio中的概念,是SelectableChannel注册到Selector后返回的一个token
booleanreadPending未知,带着问题往下看,后面在来解答
private finalRunnableclearReadPendingRunnablenew Runnable() { @Override public void run() { clearReadPending0(); } }未知,带着问题往下看,后面在来解答
privateChannelPromiseconnectPromise表示的发起连接的一个Future
privateFuture<?>connectTimeoutFuture连接超时的Future
privateSocketAddressrequestedRemoteAddress未知,带着问题往下看,后面在来解答

1.3 AbstractNioMessageChannel

修饰符类型字段含义
AbstractNioMessageChannelbooleaninputShutdown未知,带着问题往下看,后面在来解答

1.4 NioServerSocketChannel

修饰符类型字段含义
NioServerSocketChannelprivate finalServerSocketChannelConfigconfig监听套接字的配置

2 NioServerSocketChannel的默认构造函数做了什么

2.1 对AbstractChannel中的某些字段赋值

  1. parent:赋值为null,因为现在是已给监听套接字;

  2. id: new一个DefaultChannelId为其赋值

  3. unsafe:protected abstract AbstractUnsafe newUnsafe();调这个方法为其赋值,这个方法是抽象方法;因为目前是

    NioServerSocketChannel 这个类,因此它的实现在io.netty.channel.nio.AbstractNioMessageChannel#newUnsafe

    @Override
    protected AbstractNioUnsafe newUnsafe() {
    return new NioMessageUnsafe();
    }
    
  4. pipeline赋值为new DefaultChannelPipeline(this);
    

2.2 对AbstractNioChannel中的某些字段赋值

调用jdk的方法构建出一个监听套接字:

public class NioServerSocketChannel extends AbstractNioMessageChannel
                             implements io.netty.channel.socket.ServerSocketChannel {

    //...
    private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider();

    private static ServerSocketChannel newSocket(SelectorProvider provider) {
        try {
            /**
             *  Use the {@link SelectorProvider} to open {@link SocketChannel} and so remove condition in
             *  {@link SelectorProvider#provider()} which is called by each ServerSocketChannel.open() otherwise.
             *
             *  See <a href="https://github.com/netty/netty/issues/2308">#2308</a>.
             */
            return provider.openServerSocketChannel();
        } catch (IOException e) {
            throw new ChannelException(
                    "Failed to open a server socket.", e);
        }
    }
    //...
}

以上的newSocket方法构建出一个java原生的ServerSocketChannel,这个不是netty中定义的ServerSocketChannel

为AbstractNioChannel的某些字段赋值

  1. SelectableChannel ch:用java原生的ServerSocketChannel为其赋值

  2. int readInterestOp:用SelectionKey.OP_ACCEPT为其赋值

  3.  ch设置为非阻塞:ch.configureBlocking(false);

2.3 对NioServerSocketChannel中的config字段赋值

config = new NioServerSocketChannelConfig(this, javaChannel().socket());

其中javaChannel()返回的是AbstractNioChannel中的SelectableChannel ch;socket()返回的则是ServerSocket

2.4 代码详情

NioServerSocketChannel.png