Netty源码分析--Channel注册&绑定端口(下)(七)
接下来,我们看到的就是两个非常重要的方法

就是 processSelectedKeys() 和 runAllTasks() 方法了。
selectionKey中ready的事件,如accept、connect、read、write等,由processSelectedKeys方法触发。属于I/O任务。
添加到taskQueue中的任务,如register0、bind0等任务,由runAllTasks方法触发。属于非I/O任务。
两种任务的执行时间比由变量ioRatio控制,默认为50,则表示允许非IO任务执行的时间与IO任务的执行时间相等。
我们看一下 processSelectedKeys() 方法, 因为 selectedKeys != null 所以进入 processSelectedKeysOptimized() 方法。
由于没有这里只是启动服务端,没有客户端接入进来,所以我们先跳过processSelectedKeys(),一会我们结合客户端接入来讲这里。
直接看 runAllTasks() 方法。

Runnable task = pollTask(); 这个就是从 taskQueue 中拿出一个task。
然后循环执行这个任务, safeExecute(task)。

这个方法也是很简单,就是直接执行Runnable接口中的run()方法(这里并不是启动一个线程,而是仅仅的执行一个普通的run方法)。
大家想一下这里的这个task应该是什么呢?

大家还记得这段代码吗? 就是这个 register0() 方法。

我们先进入到 doRegister() 方法

继续传入当前的eventloop中的selector, opt = 0, 第三个参数 this 就是当前的 NioServerSocketChannel。 进入register 方法

大家看我圈出来的这一句,熟悉吗?我当时将NIO的时候是不是讲到了。
这里就是把当前的channel注册到这个多路复用器上。并且把 NioServerSocketChannel 传进去当做附件 attach, 注册的 interestOps = 0
好了,当执行完task,由于是一个死循环,那么会继续执行刚刚的整个过程。

好了,总结一下: 也就是说有一个线程一直在这里不断循环的等待新的 selectionKey中ready的事件,如accept、connect、read、write等。 如果有待处理的task,将会去优先处理的task.
一会我们会启动一个客户端看一下是怎么交互的。
整个注册完成之后,接下来就是 绑定端口 ,将服务对外开放出去。
我们看下AbstractBootstrap中的 doBind() 方法。

由于整个注册过程是异步的,所以这里 regFuture.isDone() 是否已经完成,如果完成直接执行doBind0(),如果没有完成,那么就监听异步响应方法,等待成功之后,再执行doBind0()方法。
我们进入doBind0()方法

我们看其实就是向eventLoop中的任务队列中添加一个task。
这里我们debug来看一下
另外在 AbstractBootstrap中打一个断点,在这里等待注册事件先完成。

好的,我们启动服务端。

断点进来了, 我们再在 NioEventLoop 中打一个断点,因为这里是处理task的地方

我们发现有一个主线程,一个子线程,如下图

切换到子线程,我们看下 task 的执行过程。

因为switch中的hasTask() 是true,那么我们就直接看


从任务队列中取出一个task,我们看到就是刚刚我们的那个任务。然后通过safeExecute(task)执行run方法

继续F5。我们看进入到了runnable中的run方法。

接下来就是一段链式调用,链式访问pipleline中的handler TailContext -> ServerBootstrapAcceptor -> LoggingHandler -> HeadContext

TailContext 和 ServerBootstrapAcceptor 中没有bind方法,直接进入LoggingHandler的bind方法,打一个日志

继续f5进入到 HeadContext中的bind方法


先判断是否激活,如果没有,则稍后链式调用handlers中的 channelActive()方法。
进入doBind方法

ok,到这里绑定端口成功。
目前为止,Server服务端启动完成,接下来我们看一下,一个客户端是怎么接入进来并且进行读写操作的。
Netty源码分析--Channel注册&绑定端口(下)(七)的更多相关文章
- Netty源码分析--Channel注册(上)(五)
其实在将这一节之前,我们来分析一个东西,方便下面的工作好开展. 打开启动类,最开始的时候创建了一个NioEventLoopGroup 事件循环组,我们来跟一下这个. 这里bossGroup, 我传入了 ...
- Netty源码分析--Channel注册(中)(六)
接上一篇,我们继续看 不知道大家第一次看这段代码的时候有没有一脸懵逼,反正我是一脸懵,为什么这个if else 最终都是调用的register0方法,都是一样的. 其实这里就是为什么Netty是线程安 ...
- Netty源码分析-- 处理客户端接入请求(八)
这一节我们来一起看下,一个客户端接入进来是什么情况.首先我们根据之前的分析,先启动服务端,然后打一个断点. 这个断点打在哪里呢?就是NioEventLoop上的select方法上. 然后我们启动一个客 ...
- Netty源码分析第4章(pipeline)---->第7节: 前章节内容回顾
Netty源码分析第四章: pipeline 第七节: 前章节内容回顾 我们在第一章和第三章中, 遗留了很多有关事件传输的相关逻辑, 这里带大家一一回顾 首先看两个问题: 1.在客户端接入的时候, N ...
- Netty源码分析第1章(Netty启动流程)---->第5节: 绑定端口
Netty源码分析第一章:Netty启动步骤 第五节:绑定端口 上一小节我们学习了channel注册在selector的步骤, 仅仅做了注册但并没有监听事件, 事件是如何监听的呢? 我们继续跟第一小节 ...
- Netty源码分析第1章(Netty启动流程)---->第4节: 注册多路复用
Netty源码分析第一章:Netty启动流程 第四节:注册多路复用 回顾下以上的小节, 我们知道了channel的的创建和初始化过程, 那么channel是如何注册到selector中的呢?我们继 ...
- Netty源码分析第1章(Netty启动流程)---->第3节: 服务端channel初始化
Netty源码分析第一章:Netty启动流程 第三节:服务端channel初始化 回顾上一小节的initAndRegister()方法: final ChannelFuture initAndRe ...
- Netty源码分析第3章(客户端接入流程)---->第4节: NioSocketChannel注册到selector
Netty源码分析第三章: 客户端接入流程 第四节: NioSocketChannel注册到selector 我们回到最初的NioMessageUnsafe的read()方法: public void ...
- Netty源码分析(前言, 概述及目录)
Netty源码分析(完整版) 前言 前段时间公司准备改造redis的客户端, 原生的客户端是阻塞式链接, 并且链接池初始化的链接数并不高, 高并发场景会有获取不到连接的尴尬, 所以考虑了用netty长 ...
随机推荐
- android Bluetooth程序设计
Bluetooth一个简短的引论 蓝牙,是一种短距离通信配套设备(一般10m中)无线技术. 包含移动电话.PDA.无线耳机.笔记本电脑.相关外设等众多设备之间进行无线信息交换.利用"蓝牙&q ...
- ubuntu 12.04 简单配置samba服务,实现主机与虚拟机互通(设置Windows虚拟盘)
环境: virtualbox ubuntu12.04 首先,如果你到这步了,说明你的window与linux的网络已经配好了,他们之间是可以互相Ping通的,如果没有,请看我以前的文章 由于我linu ...
- OpenGL+VS2012编译环境配置
OpenGL库主体分为三部分,分别是 gl(OpenGL核心库) glu(Utility Library,OpenGL实用库) glut(Utility Toolkit,OpenGL实用工具库) gl ...
- Linux性能测试 free命令
命 令: free功能说明:显示内存状态.语 法: free [-bkmotV][-s <间隔秒数>]补充说明:free指令会显示内存的使用情况,包括实体内存,虚拟的交换文件内存,共享内存 ...
- Poco logger 日志使用小析
Poco logger 日志使用小析 Poco logger 日志使用小析 日志 logger 库选择 Pocologger 架构简析 步骤一 生成消息 步骤二 写入logger 步骤三 导入chan ...
- WPF Clip实现百叶窗
原文:WPF Clip实现百叶窗 效果图; 后台代码: public MainWindow() { InitializeComponent(); ...
- JDBC学习笔记——增删改查
1.数据库准备 要用JDBC操作数据库,第一步当然是建立数据表: ? 1 2 3 4 5 6 CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_I ...
- Linux(CentOS 7)+ Nginx(1.10.2)+ Mysql(5.7.16)+ PHP(7.0.12)完整环境搭建
首先安装Linux系统,我以虚拟机安装来做示例,先去下载 VitualBox,这是一款开源的虚拟机软件,https://www.virtualbox.org 官网地址.或者是VMware,www.vm ...
- String关于BeanFactory与ApplicationContext的简单区别
1.创建的方式不同 ApplicationContext: ApplicationContext context = new ClassPathXmlApplicationContext(" ...
- linux没有 conio.h解决的方式
conio.h不是C标准库中的头文件,在ISO和POSIX标准中均未定义. conio是Console Input/Output(控制台输入输出)的简写,当中定义了通过控制台进行数据输入和数据输出的函 ...