3-2 服务端Channel的创建

Posted programmlover

tags:

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

一  问题

 1.  服务端socket在哪里初始化

 2.  在哪里accept连接

 

二  Netty启动Channel过程

 1.  创建服务端Channel

 2.  初始化服务端Channel

 3.注册selector

 4.端口绑定

 

三  Netty启动Channel过程: 创建服务端Channel

  1.  AbstractBootstrap.bind()  //用户代码入口

技术图片

  2.  AbstractBootstrap.initAndRegister()  //初始化并注册 

技术图片 

  3.  newChannel()  //创建服务端channel

    newChannel()只是ChannelFactory接口的fang方法,具体实现是掉的哪个实现类

    查看 ServerBootstrap 对象,会发现 ServerBootstrap 制定了了NioserverSocketChannel.class这个channel

技术图片

 

 

     进入channel()方法,会发现返回了一个 ReflectiveChannelFactory 的ChannelFactory

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

    查看 ReflectiveChannelFactory.newChannel() ,原来newChannel()只是用反射的方法创建了一个NioServerSocketChannel类型的Channel对象

    @Override
    public T newChannel() {
        try {
            return clazz.newInstance();
        } catch (Throwable t) {
            throw new ChannelException("Unable to create Channel from class " + clazz, t);
        }
    }

 

四  NioServerSocketChannel构造函数大纲

 1. newSocket()  //通过JDK底层来创建jdk channel

 2.NioServerSocketChannelConfig()  //tcp参数配置类

 3.AbstractNioChannel.configureBlocking(false)  //设置为非阻塞模式

 4.AbstractChannel.AbstractChannel()  //创建id,unsafe,pipeline

 

五  NioServerSocketChannel创建流程

 1.无参构造方法中调用newSocket()方法并传入一个DEFAULT_SELECTOR_PROVIDER,DEFAULT_SELECTOR_PROVIDER=SelectorProvider.provider(),newSocket()方法调用jdk的SelectorProvider.provider().openServerSocketChannel() 创建一个jdk底层的一个 ServerSocketChannel

    public NioServerSocketChannel() {
        this(newSocket(DEFAULT_SELECTOR_PROVIDER));
    }
    private static ServerSocketChannel newSocket(SelectorProvider provider) {
        try {
            return provider.openServerSocketChannel();
        } catch (IOException e) {
            throw new ChannelException(
                    "Failed to open a server socket.", e);
        }
    }

 2.创建一个 NioServerSocketChannelConfig 配置类

    public NioServerSocketChannel(ServerSocketChannel channel) {
        super(null, channel, SelectionKey.OP_ACCEPT);
        config = new NioServerSocketChannelConfig(this, javaChannel().socket());
    }

 3.调用父类的 AbstractNioChannel 构造器,设置配置configureBlocking为false,表明是一个非阻塞的IO模式

    protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
        super(parent);
        this.ch = ch;
        this.readInterestOp = readInterestOp;
        try {
            ch.configureBlocking(false);
        } catch (IOException e) {
            try {
                ch.close();
            } catch (IOException e2) {
                if (logger.isWarnEnabled()) {
                    logger.warn(
                            "Failed to close a partially initialized socket.", e2);
                }
            }

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

 4.  再调用父类AbstractChannel构造器,设置id, unsafe,pipeline属性

    protected AbstractChannel(Channel parent) {
        this.parent = parent;
        id = DefaultChannelId.newInstance();
        unsafe = newUnsafe();
        pipeline = new DefaultChannelPipeline(this);
    }

  到这里,服务端Channel创建完成

 

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

Netty入门——组件(Channel)一

Netty入门——组件(Channel)二

[Go] 通过 17 个简短代码片段,切底弄懂 channel 基础

netty服务端基本的工作原理

netty系列之:channel和channelGroup

Netty入门——springboot框架开发一个简单的服务器端和客户端