参考文献:极客时间傅健老师的《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的猜测:放大果断,缩小谨慎(需要连续两次判断)

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

最新文章

  1. Java性能调优之:idea变慢解决
  2. CSS滚动条
  3. android之HttpClient
  4. [转]使用 google gson 转换Timestamp或Date类型为JSON字符串.
  5. 字符串复制strncpy
  6. 实现关闭窗口IE不提示兼容火狐
  7. AC自动机学习笔记
  8. ES6笔记② 箭头函数
  9. jquery实现点击改变背景色,点击其他恢复原来背景色,被点击的改变背景色
  10. Android 基础一 TextView,Style样式,Activity 传值,选择CheckBox 显示密码
  11. Liunx中三种网络模式配置及Xshell连接
  12. 100道c++面试题(上)
  13. 2019.03.01 bzoj2555: SubString(sam+lct)
  14. linux log
  15. git常用命令(todo...)
  16. Python学习--打码平台
  17. 反恐24小时第一季/全集24 Live Another Day迅雷下载
  18. ErrorProvider控件使用
  19. OAF 供应商门户添加功能标签后获取当前供应商VendorId的方法
  20. BZOJ3203 SDOI2013保护出题人(三分)

热门文章

  1. 23333 又是一篇水文章(以下是各种复制来的关于maven转成eclipse项目)
  2. 一图了解DLL和SYS的区别
  3. vue怎么引入echats并使用 (柱状图 字符云)
  4. Windows下MongoDB的安装过程及基本配置
  5. Intellij IDEA导入JAVA项目并启动(哈哈哈,天天都有人问)
  6. (八)爬虫之js调试(登陆知乎)
  7. Js 实现页面缩放
  8. 官网引用的axios,lodash文件在脚手架中如何使用?
  9. 虚拟化技术实现 — KVM 的 CPU 虚拟化
  10. 【404】int main(int argc,char * argv[]) windows 下的使用