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次)。
我只想做的更好,仅此而已。
Netty源码剖析-构建链接的更多相关文章
- Netty 源码剖析之 unSafe.write 方法
前言 在 Netty 源码剖析之 unSafe.read 方法 一文中,我们研究了 read 方法的实现,这是读取内容到容器,再看看 Netty 是如何将内容从容器输出 Channel 的吧. 1. ...
- Netty源码剖析-关闭服务
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线: ----源码: 先在服务端加个断点和修改下代码:如 ...
- Netty源码剖析-断开连接
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线: ----源码: 在NioEventLoop的unsa ...
- Netty源码剖析-发送数据
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! 开始之前先介绍下Netty写数据的三种方式: ①:write:写到一 ...
- Netty源码剖析-业务处理
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线:worker thread 触发pipeline.fi ...
- Netty源码剖析-接受数据
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线:worker thread ①多路复用器(Select ...
- Netty源码剖析-启动服务
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! --1主线分两步: 一:首先在our thread里,如果写在mai ...
- Netty学习笔记(三)——netty源码剖析
1.Netty启动源码剖析 启动类: public class NettyNioServer { public static void main(String[] args) throws Excep ...
- Netty 源码剖析之 unSafe.read 方法
目录: NioSocketChannel$NioSocketChannelUnsafe 的 read 方法 首先看 ByteBufAllocator 再看 RecvByteBufAllocator.H ...
随机推荐
- Java面向对象2(G~J)
G 织女的红线(SDUT 2240) import java.util.Scanner; import java.text.DecimalFormat; class Sum { double x ...
- 使用scp上传ssh公钥到服务器
$ scp ~/.ssh/id_rsa.pub root@xxx.xxx.xxx.xxx:.ssh/id_rsa.pub $ ssh root@xxx.xxx.xxx.xxx $ cat ~/.ssh ...
- Devexpress GridControl中 repositoryItemCheckEdit作为选择列以及作为显示列的使用方法
一.在gridcontrol列表控件中使用单选框作为选择列,这里有两种方式. 方式一:选择gridcontrol控件的Run Designer按钮,添加一列,设置该列的ColumnEdit为check ...
- WINRAR弹窗堆栈
0:000> db 004ddfa8004ddfa8 6f 00 70 00 65 00 6e 00-00 00 00 00 2d 00 6e 00 o.p.e.n.....-.n. 03063 ...
- csp-s模拟90
T1: 每格的不透明度相当与一个边权,转化为从起点到终点所有路径的最大值.实现最长路,最好用$dijk$. T2: 对于$N=100$,$M=8$,考虑状压$dp$.要用一种状态表示某一行的矩形覆盖情 ...
- spring boot 学习常用网站
springboot的特性 https://www.cnblogs.com/softidea/p/5644750.html 1.自定义banner https://www.cnblogs.com/cc ...
- jQuery 的on()方法
jQuery 的on()方法 一.总结 一句话总结: 1.普通添加事件:$("a").on("click", function () {执行的代码}) 2.未创 ...
- dll程序开发总结
1.修改生成的dll名称 VS2012中选中某个项目,项目--属性--配置属性--连接器--常规--输出文件
- Antecedent Membership Functions相关资料
属于模糊控制领域 前件隶属函数(Antecedent Membership Functions) 基于模糊近似的强化学习方法研究 - 豆丁网 https://www.docin.com/p-13022 ...
- Qt编写安防视频监控系统8-双击节点
一.前言 在所有的视频监控系统中,双击摄像机的节点,对应摄像机加载到当前焦点通道显示,这个都是必须具备的功能,还有一些厂家会做双击NVR节点,自动加载该NVR下的所有摄像机全部显示,从通道1开始到通道 ...