美文网首页程序员
netty源码分析(13)- 创建NioSocketChanne

netty源码分析(13)- 创建NioSocketChanne

作者: Jorgezhong | 来源:发表于2019-02-25 10:01 被阅读12次

    上一节研究了新连接接入的过程,通过检测IO事件轮询新连接,当前成功检测到连接接入事件之后,会调用NioServerSocketChannel#doReadMessages()方法,进行创建NioSocketChannel

     @Override
        protected int doReadMessages(List<Object> buf) throws Exception {
            //获取jdk底层的channel:客户端channel
            SocketChannel ch = SocketUtils.accept(javaChannel());
    
            try {
                if (ch != null) {
                    //将jdk底层的channel封装到netty的channel,并存储到传入的容器当中
                    //this为服务端channel
                    buf.add(new NioSocketChannel(this, ch));
                    //成功和创建 客户端接入的一条通道,并返回
                    return 1;
                }
            } catch (Throwable t) {
                logger.warn("Failed to create a new channel from an accepted socket.", t);
    
                try {
                    ch.close();
                } catch (Throwable t2) {
                    logger.warn("Failed to close a socket.", t2);
                }
            }
    
            return 0;
        }
    

    本节研究创建NioSocketChannel,即客户端channel的过程

    查看原代码做了两件事,调用父类构造方法,实例化一个NioSocketChannelConfig

        public NioSocketChannel(Channel parent, SocketChannel socket) {
            super(parent, socket);
            //实例化一个NioSocketChannelConfig
            config = new NioSocketChannelConfig(this, socket.socket());
        }
    
    • 首先看看NioSocketChannelConfig实例化。主要是保存了javaSocket,并且通过setTcpNoDelay(true);禁止了tcp的Nagle算法,目的是为了尽量让小的数据包整合成大的发送出去,降低延时。
            private NioSocketChannelConfig(NioSocketChannel channel, Socket javaSocket) {
                super(channel, javaSocket);
                calculateMaxBytesPerGatheringWrite();
            }
    
        public DefaultSocketChannelConfig(SocketChannel channel, Socket javaSocket) {
            super(channel);
            if (javaSocket == null) {
                throw new NullPointerException("javaSocket");
            }
            //保存socket
            this.javaSocket = javaSocket;
    
            // Enable TCP_NODELAY by default if possible.
            if (PlatformDependent.canEnableTcpNoDelayByDefault()) {
                try {
                    //禁止Nagle算法,目的是为了让小的数据包尽量集合成大的数据包发送出去
                    setTcpNoDelay(true);
                } catch (Exception e) {
                    // Ignore.
                }
            }
        }
    
    • 接着查看NioSocketChannel父类构造方法,主要是保存客户端注册的读事件、channel为成员变量,以及设置柱塞模式为非阻塞
        public NioSocketChannel(Channel parent, SocketChannel socket) {
            super(parent, socket);
            //实例化一个NioSocketChannelConfig
            config = new NioSocketChannelConfig(this, socket.socket());
        }
        protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) {
            //传入感兴趣的读事件:客户端channel的读事件
            super(parent, ch, SelectionKey.OP_READ);
        }
    
        protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
            super(parent);
            //保存客户端channel为成员变量
            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);
            }
        }
    

    调用父类的构造方法,是设置该客户端channel对应的服务端channel,以及channel的id和两大组件unsafepipeline

        protected AbstractChannel(Channel parent) {
            //parent为创建次客户端channel的服务端channel(服务端启动过程中通过反射创建的)
            this.parent = parent;
            id = newId();
            unsafe = newUnsafe();
            pipeline = newChannelPipeline();
        }
    

    相关文章

      网友评论

        本文标题:netty源码分析(13)- 创建NioSocketChanne

        本文链接:https://www.haomeiwen.com/subject/hncwyqtx.html