zoukankan      html  css  js  c++  java
  • Netty源码剖析-构建链接

    参考文献:极客时间傅健老师的《Netty源码剖析与实战》Talk is cheap.show me the code!

    ----主线:

      和启动一样也是有两个线程完成的,boss thread 和 worker thread;

    boss thread:

       ①NioEventLoop中的selector轮询创建连接事件(OP_ACCEPT)

       ②创建socket channel

       ③初始化socket channel 并从 worker group 中选择一个NioEventLoop

    worker thread:

       ④将socket channel 注册到选择的NioEventLoop的selector

       ⑤注册读事件(OP_READ)到selector上

    ----源码解释:

      在NioEventLoop中找到run();在run()里面有个processSelectedKeys();

     点进去后

     其中processSelectedKeysOptimized();不用jdk的selector.selectedKeys(),性能更好,垃圾回收更少;接着跟进去;

     打上断点,这个地方开始就轮询事件了。然后debug启动服务端和客户端(代码参考https://www.cnblogs.com/-qilin/p/11671763.html)!

     然后进入该方法,然后依次执行;

     其中16就代表着OP_ACCEPT;进入unsafe.read().中有这么个代码

     接着再进doReadMessages();SocketChannel ch = SocketUtils.accept(javaChannel());表示接受新连接创建SocketChannel;

     接着再跟进去

     上图的断点return serverSocketChannel.accept();表示非阻塞模式下,没有连接请求时返回null;接着继续往下走会来到这个地方:

    pipeline.fireChannelRead(readBuf.get(i));可以看出有多个handler,接着找到ServerBootstrapAcceptor这个handler,然后找到channelRead()方法,打个断点跳过来:

     往下走childGroup.register(child).addListener();加个断点跟进去:

    然后在一步一步的跟进register()后来到下面的代码,打个断点之后再跟进:

     进入register0()

    看到熟悉的doRegister(),跟进去看看:

     

     这里和上篇源码解释的一样,继续往下走:

     在跳转到head上,找到read()方法:

    然后进去看看

     

     又看到熟悉的doBeginRead();跟进去看看

     与之不同的是这时候readInterestOp不是16而是1了,是OP_READ而非OP_ACCEPT了。这时候已经走完了。可以看控制台:

     ----总结:

      接收连接的本质:

      selector.select()/selectNow()/select(timeoutMillis)发现OP_ACCEPT事件,处理:

        SocketChannel socketChannel = serverSocketChannel.accopt();

        selectionKey = javaChannel().register(eventLoop().unwrappedSelector(),0,this);

        selectKey.interestOps(OP_READ);    

     创建连接的初始化和注册是通过pipeline.fireChannelRead在ServerBootstrapAcceptor中完成的。

    第一次Register并不是监听OP_READ,而是0;

      selectionKey = javaChannel().register(eventLoop().unwrappedSelector(),0,this);

    最终监听OP_READ是通过“Register”完成后的fireChannelActive(io.netty.channel.AbstractChannel.AbstractUnsafe#register0中)来触发的;

    Worker's NioEventLoop是通过Register操作执行来启动。

    接受连接的读操作,不会尝试读取更多次(16次)。

    我只想做的更好,仅此而已。

  • 相关阅读:
    第二季-专题11-世界一下变大了-MMU
    第二季-专题10-C语言环境初始化
    第二季-专题9--代码搬移不可少
    第二季-专题8-不用内存怎么行
    第二季-专题6-点亮指路灯
    第二季-专题7-ARM跑快了---时钟初始化
    第二季-专题5-核心初始化
    第二季-专题4-我是bootloader设计师
    消除苹果系统对边框的优化
    css3
  • 原文地址:https://www.cnblogs.com/-qilin/p/11812179.html
Copyright © 2011-2022 走看看