码迷,mamicode.com
首页 > 其他好文 > 详细

3-2 服务端Channel的创建

时间:2019-11-24 21:09:21      阅读:96      评论:0      收藏:0      [点我收藏+]

标签:selector   accept   blocking   调用   try   led   rri   point   efault   

一  问题

 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的创建

标签:selector   accept   blocking   调用   try   led   rri   point   efault   

原文地址:https://www.cnblogs.com/programmlover/p/11924247.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!