zoukankan      html  css  js  c++  java
  • 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的猜测:放大果断,缩小谨慎(需要连续两次判断)

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

  • 相关阅读:
    10个最好的游戏开发在线资源
    程序员什么时候该考虑辞职
    程序员常去的14个顶级开发社区
    如何成为10倍速的程序员
    (通用)深度学习环境搭建:tensorflow安装教程及常见错误解决
    20行JS代码实现贪吃蛇
    程序员必备工具目录
    发布 Google Chrome插件教程
    高并发思路
    30分钟入门Java
  • 原文地址:https://www.cnblogs.com/-qilin/p/11813245.html
Copyright © 2011-2022 走看看