参考文献:极客时间傅健老师的《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源码剖析-构建链接的更多相关文章

  1. Netty 源码剖析之 unSafe.write 方法

    前言 在 Netty 源码剖析之 unSafe.read 方法 一文中,我们研究了 read 方法的实现,这是读取内容到容器,再看看 Netty 是如何将内容从容器输出 Channel 的吧. 1. ...

  2. Netty源码剖析-关闭服务

    参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线:  ----源码: 先在服务端加个断点和修改下代码:如 ...

  3. Netty源码剖析-断开连接

    参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线: ----源码: 在NioEventLoop的unsa ...

  4. Netty源码剖析-发送数据

    参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! 开始之前先介绍下Netty写数据的三种方式: ①:write:写到一 ...

  5. Netty源码剖析-业务处理

    参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线:worker thread 触发pipeline.fi ...

  6. Netty源码剖析-接受数据

    参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线:worker thread ①多路复用器(Select ...

  7. Netty源码剖析-启动服务

    参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! --1主线分两步: 一:首先在our thread里,如果写在mai ...

  8. Netty学习笔记(三)——netty源码剖析

    1.Netty启动源码剖析 启动类: public class NettyNioServer { public static void main(String[] args) throws Excep ...

  9. Netty 源码剖析之 unSafe.read 方法

    目录: NioSocketChannel$NioSocketChannelUnsafe 的 read 方法 首先看 ByteBufAllocator 再看 RecvByteBufAllocator.H ...

随机推荐

  1. ERRORS: ?: (corsheaders.E013) Origin '*' in CORS_ORIGIN_WHITELIST is missing scheme or netloc HINT:

    报错信息 ERRORS: ?: (corsheaders.E013) Origin '*' in CORS_ORIGIN_WHITELIST is missing scheme or netloc H ...

  2. Spring Cloud Gateway(二):Spring Cloud Gateway整合Eureka应用

    Spring Cloud Gateway 应用概述 下面的示例启动两个服务:gataway-server 和 user-service 都注册到注册中心 Eureka上,客户端请求后端服务[user- ...

  3. elasticsearch _update api 更新部分字段内容

    https://www.elastic.co/guide/cn/elasticsearch/guide/current/partial-updates.htmlupdate 请求最简单的一种形式是接收 ...

  4. Git 中无法忽略 .xcuserstate 的解决方法

    1.查看代码变化git status 2.接着输入 git rm –cached 刚才复制的地址 ,如下.git rm --cached RxSwift/Rx.xcodeproj/xcuserdata ...

  5. 攻防世界RE1 writeup

    解题过程 将题目给出的exe文件拖入ida中,查看main函数. 分析函数的逻辑,发现用户需要输出一个字符串,存储到变量v9中.如果v9的值与v5的值相等则会打印unk_413e90中的值,否则打印a ...

  6. EEPROM与FLASH

    最初的ROM rom最初不能编程,出厂什么内容就永远什么内容,不灵活.后来出现了prom,可以自己写入一次,要是写错了,只能换一片,自认倒霉. 人类文明不断进步,终于出现了可多次擦除写入的EPROM, ...

  7. Airbnb架构要点分享——阅读心得

    目前,Airbnb已经使用了大约5000个AWS EC2实例,其中大约1500个实例用于部署其应用程序中面向Web的部分,其余的3500个实例用于各种分析和机器学习算法.而且,随着Airbnb的发展, ...

  8. err="etherbase address must be explicitly specified"

    如果要初始化区块链的话就用创始区块   如果通过创世区块来初始化区块链的话,首先需要一个初始化区块链的json文件,如下. { "config": { "chainId& ...

  9. x86 linux下如何交叉编译?

    答: 需要首先指定两个环境变量CROSS_COMPILE和ARCH 如交叉编译arm64的程序: export CROSS_COMPILE="aarch64-linux-gnu-" ...

  10. Qt编写安防视频监控系统11-动态换肤

    一.前言 Qt中的动态换肤技术是非常一流的,直接调用qApp->setStyleSheet(qss);就可以对整个应用程序进行换肤,如果样式表内容不多,或者对应的贴图不对,效率还是蛮好的,不过据 ...