• netty4.1.6源码2-------创建服务端的channel


    1. netty在哪里调用jdk底层的socket去创建netty服务端的socket。
    2. 在哪里accept连接。
    服务端的启动:
    1. 调用jdk底层的api去创建jdk的服务端的channel。Netty封装成自己的channel同时创建一些组件绑定在这个channel上面。
    2. 初始化服务端的channel。
    3. 注册selector,netty将jdk底层的channel注册到事件轮询器selector上面,并把服务端的channel作为attachment附加到jdk底层的channel上面,有事件轮询出来的时候就可以直接拿这个attachment,这个attachment就是netty封装的服务端的channel。
    4. 端口绑定,调用jdk底层的api作为端口的监听。

    1. 创建服务端的channel:

    ChannelFuture f = b.bind(8888).sync();//服务端创建channel的入口
    final ChannelFuture regFuture = initAndRegister(); //创建服务端的channel
    final ChannelFuture initAndRegister() {        
    Channel channel = null;        
    try {            
    channel = channelFactory.newChannel(); //.channel方法设置channelFactory,channelFactory是ReflectiveChannelFactory            
    init(channel);        
    }
    public class ReflectiveChannelFactory<T extends Channel> implements ChannelFactory<T> {
    public ReflectiveChannelFactory(Class<? extends T> clazz) {
       if (clazz == null) {
           throw new NullPointerException("clazz");
       }
       this.clazz = clazz;
    }    
            @Override
        public T newChannel() { //newChannel方法
            try {
                return clazz.newInstance(); //通过反射创建channel,clazz是NioServerSocketChannel.class,newInstance()调用的是构造函数
            } catch (Throwable t) {
                throw new ChannelException("Unable to create Channel from class " + clazz, t);
            }
        }
    }
    ServerBootstrap b = new ServerBootstrap();
                b.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class) //分析.channel方法,传入NioServerSocketChannel通过反射方式调用NioServerSocketChannel类的构造函数
    AbstractBootstrap类:    
    public B channel(Class<? extends C> channelClass) { //channelClass是传进来的NioServerSocketChannel.class
            if (channelClass == null) {
                throw new NullPointerException("channelClass");
            }
            return channelFactory(new ReflectiveChannelFactory<C>(channelClass));  //通过ReflectiveChannelFactory构造函数把channelClass封装成ReflectiveChannelFactory,设置channelFactory
        }
        public B channelFactory(ChannelFactory<? extends C> channelFactory) {
            if (channelFactory == null) {
                throw new NullPointerException("channelFactory");
            }
            if (this.channelFactory != null) {
                throw new IllegalStateException("channelFactory set already");
            }
            this.channelFactory = channelFactory; //设置channelFactory
            return (B) this;
        }
    NioServerSocketChannel构造函数:

    private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider();
        private static ServerSocketChannel newSocket(SelectorProvider provider) {
            try {
                return provider.openServerSocketChannel();
            } catch (IOException e) {
                throw new ChannelException("Failed to open a server socket.", e);
            }
        }
    public NioServerSocketChannel() { //构造函数
        this(newSocket(DEFAULT_SELECTOR_PROVIDER)); //newSocket创建jdk底层的Channel,服务端的channel就创建完毕了
    }
    public NioServerSocketChannel(ServerSocketChannel channel) {
            super(null, channel, SelectionKey.OP_ACCEPT);
            config = new NioServerSocketChannelConfig(this, javaChannel().socket());  // this是NioServerSocketChannel也就是netty服务端的channel,
    }
    super(null, channel, SelectionKey.OP_ACCEPT); //跟进去
    AbstractNioChannel类:
        protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
            super(parent);
            this.ch = ch; //通过newSocket创建出来的jdk底层的channel,
            this.readInterestOp = readInterestOp;
            try {
                ch.configureBlocking(false);//设置服务端的channel非阻塞模式,
            } 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);
            }
        }
    //channel有服务端和客户端的channel,都继承自AbstractChannel,
    protected AbstractChannel(Channel parent) {
            this.parent = parent;
            id = newId();//channel唯一的表示
            unsafe = newUnsafe();//channel底层tcp相关的操作
            pipeline = newChannelPipeline();
    }
  • 相关阅读:
    UI设计学习路径(一个)—好酒也怕巷子深
    shell script 入门 笔记
    HDU 4864Task(更多的联合培训学校1)(贪婪)
    XCL-Charts绘画面积图(AreaChart) 例1
    table插入标签form标记怪现象
    ECharts SSH+JQueryAjax+Json+JSP在数据库中的数据来填充ECharts在
    Xcode 6 AutoLayout Size Classes
    POJ 1984 Navigation Nightmare (数据结构-并检查集合)
    DataTable填补了实体类返回泛型集合
    Cisco C2900XL
  • 原文地址:https://www.cnblogs.com/yaowen/p/9213387.html
Copyright © 2020-2023  润新知