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的猜测:放大果断,缩小谨慎(需要连续两次判断)
我只想做的更好,仅此而已。
Netty源码剖析-接受数据的更多相关文章
- Netty源码剖析-发送数据
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! 开始之前先介绍下Netty写数据的三种方式: ①:write:写到一 ...
- Netty源码剖析-断开连接
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线: ----源码: 在NioEventLoop的unsa ...
- Netty 源码剖析之 unSafe.write 方法
前言 在 Netty 源码剖析之 unSafe.read 方法 一文中,我们研究了 read 方法的实现,这是读取内容到容器,再看看 Netty 是如何将内容从容器输出 Channel 的吧. 1. ...
- Netty源码剖析-业务处理
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线:worker thread 触发pipeline.fi ...
- Netty源码剖析-构建链接
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线: 和启动一样也是有两个线程完成的,boss threa ...
- Netty源码剖析-启动服务
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! --1主线分两步: 一:首先在our thread里,如果写在mai ...
- Netty源码剖析-关闭服务
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线: ----源码: 先在服务端加个断点和修改下代码:如 ...
- Netty学习笔记(三)——netty源码剖析
1.Netty启动源码剖析 启动类: public class NettyNioServer { public static void main(String[] args) throws Excep ...
- Netty 源码剖析之 unSafe.read 方法
目录: NioSocketChannel$NioSocketChannelUnsafe 的 read 方法 首先看 ByteBufAllocator 再看 RecvByteBufAllocator.H ...
随机推荐
- Git入门(待更)
github是什么? 以下截取自百度百科 github: GitHub 是一个面向开源及私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub. GitHub 于 ...
- 验证码的实现类ValidateCode
package com.yujie.util; import javax.imageio.ImageIO;import java.awt.*;import java.awt.image.Buffere ...
- codeforces gym #101161E - ACM Tax(lca+主席树)
题目链接: http://codeforces.com/gym/101161/attachments 题意: 给出节点数为$n$的树 有$q$次询问,输出$a$节点到$b$节点路程中,经过的边的中位数 ...
- React前端开发环境搭建
先,我们需要明确的是React和很多前端框架一样,底层都还是js以及html,即便它有着看似特殊的jsx语法. 我们要在服务端运行js,就需要依赖一个环境,和运行war包需要tomcat一类中间件一样 ...
- k8s之yaml详解
k8s之yaml详解 apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中 kind: Pod #指定创建资源的角色/类型 metadata: #资源的元数 ...
- http代理和SOCKS代理的区别
HTTP 代理按匿名功能分类(是否具有隐藏 IP 的功能) 非匿名代理:不具有匿名功能. 匿名代理.使用此种代理时,虽然被访问的网站不能知道你的 IP 地址,但仍然可 以知道你在使用代理,有些侦测 I ...
- 令人窒息的操作,nodejs面向对象。
// async函数返回一个 Promise 对象,可以使用then方法添加回调函数. // 当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句. clas ...
- 重读APUE(15)-pthread_cond_wait与while循环
即使pthead_cond_wait()和pthread_cond_timewait()没有错误返回,等待的条件也可能是假的:即使pthread_cond_timewait()返回了超时错误,关联的条 ...
- 重读APUE(2)-read返回值少于要求读取字节数
返回值: 成功返回读到的字节数,如果达到文件尾,则返回0:注意:如果有数据第一次读取会返回全部读到的字节数,下一次读取才会返回0: 出错返回-1: 返回值少于要求读取字节数的情况: 1. 读取普通文件 ...
- Oracle JDBC 连接池
1.简介 数据库连接池负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个:释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据 ...