• Netty源码剖析-接受数据


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

    ----主线:worker thread

      ①多路复用器(Selector)接受到OP_READ事件

      ②处理OP_READ事件:NioSocketChannel.NioSocketChannelUnsafe.read();

        -1分配一个初始1024字节的byte buffer来接受数据

        -2从Channel接受数据到byte buffer

        -3记录实际接受数据大小,调整下次分配byte buffer大小

        -4触发pipeline.fireChannelRead(byteBuf)把读取到的数据传播出去

        -5判断接受byte buffer是否满载而归,是:尝试继续读取直到没有数据或满16次,否:结束本轮读取,等待下次OP_READ事件

    ----源码解释:

        在NioEventLoop中的processSelectedKey()的unsafe.read()加个断点

     然后启动服务端和客户端...第一次启动的时候如下图:

     这里的channel=NioServerSocketChannel.处理的是OP_ACCEPT,我们直接放行,断点还停留在原地看看效果:

     可以清楚的看到这时候的channel=NioSocketChannel;这个时候我们跟进去看看:

     进入read()方法后可以看到这行代码,byteBuf = allocHandle.allocate(allocator);表示尽可能分配合适的大小:“guess”;下面一行“allocHandle.lastBytesRead(doReadBytes(byteBuf));”则表示读并且记录读了多少,如果读满了下次继续的话直接扩容;先跟进看看allocate();

     然后在进去guess();

     进来可以发现返回的是“1024”,接着往下走:

    进入doReadBytes();

    可以发现这里有一个“byteBuf.writeBytes()”;接着跟进去看看:

    再跟进"setBytes()"

     这里就能看出来是“SocketChannel.read()”;然后再接着往下执行返回:

     不难看出读取了一次:

     下面的pipeline.fireChannelRead(byteBuf);则是处理业务逻辑的地方,pipeline上执行,继续往下走:

     allocHandle.readComplete();记录这次读事件共读了多少数据,计算下次分配的大小

    pipeline.fireChannelReadComplete();相当于完成本次读事件的处理

    ----总结:

      读取数据的本质:sun.nio.ch.SocketChannelImpl#read(java.nio.ByteBuffer)

      NioSocketChannel read()是读数据,NioServerSocketChannel read()是创建连接

      pipeline.fireChannelReadComplete();表示一次事件处理完成

        pipeline.fireChannelRead(byreBuf);一次读取数据完成,一次读事件处理可能会包含多次读数据操作

      为什么最多只尝试读取16次?“雨露均沾”

      AdaptiveRecvByteBufAllocator对bytebuf的猜测:放大果断,缩小谨慎(需要连续两次判断)

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

  • 相关阅读:
    python 发包爬取中国移动充值页面---可判断手机号是否异常
    python利用selenium和safari浏览器驱动实现新浪微博自动点赞 Demo
    Django学习报错记录
    nginx和tomcat的区别
    Mac主机映射到域名
    mac下eclipse安装svn插件-subclipse
    移动端——等分,居中
    移动端——重置样式
    M端页面-绝对定位布局
    jquery-练习-折叠效果
  • 原文地址:https://www.cnblogs.com/-qilin/p/11813245.html
Copyright © 2020-2023  润新知