Netty中的永动机

Stella981
• 阅读 545

永动机即'永远运动的机器'.

作为服务端时, 需要接收客户端的连接, 需要接收客户端的数据, 或者向客户端发送数据.

既然需要接收客户端的连接, 那么就需要一个IO线程永远的执行一个无限循环.只有一直循环着, 才能一直接收新的连接.

NioEventLoop的底层绑定一个线程, 这个线程在启动之后, 就会一直无限循环着, 而且只做三件事

1.轮询IO事件

2.处理IO事件

3.执行任务

Netty中的永动机

当有新的客户端连接到服务端的时候(TCP三次握手已经完成), 服务端的IO线程就会轮询到有客户端的连接****事件. 接下来就会处理这个连接事件.

IO线程会创建一个针对这个客户端与之对应的NioSocketChannel, 然后把这个Channel注册到另一类NioEventLoop(它的底层也会绑定一个线程)上.

Netty中的永动机

从图中可以看出, 右侧的IO线程只会负责读写事件, 并不会负责连接事件.

当客户端给服务端发送数据的时候, 服务端IO线程轮询到读事件, 接下来就会处理这个读事件. 会读取到客户端发送过来的数据, 经过解码器解码, 再把数据传给业务Handler进行处理.

然而一般情况下, 当服务端需要向客户端写数据的时候, 直接调用相应的函数(writeAndFlush)即可, 并不会涉及到写事件. 那么什么时候才会涉及到写事件呢? 当网络出现拥堵的情况, 或者客户端没有及时处理服务端发给它的数据. 那么服务端的Socket的TCP缓冲区就会被写满, 这个时候再向缓冲区写数据就会失败, Netty就会注册一个写事件. 当TCP缓冲区可写的时候, Netty就会继续将之前没有写完的数据,再次向TCP缓冲区写.

如果把Netty的服务端比作一台大型的机器. 那么在这个机器里, 有好几个一直运作地大齿轮(每个NioEventLoop就是一个大齿轮). 这些大齿轮一直转着,一直转着, 从不停止.

以上说了服务端的三个IO事件, 分别是连接事件, 读事件, 写事件. 准确的说应该是接收连接事件, 读事件, 写事件.

因为在客户端也有三个IO事件, 分别是连接事件, 读事件, 写事件. 如下图

Netty中的永动机

如上图右侧所示, 客户端轮询着连接事件, 读事件和写事件. 读写事件和服务端一样, 说一下连接事件.

Netty在进行TCP三次握手的时候, 由于网络等原因, Netty并没有一直等待着连接完成, 客户端在发起连接之后, 便注册了一个连接事件. 当TCP三次握手完成之后, IO线程轮询到了连接完成事件. 接下来就会做一些连接完成的后续工作, 同时取消连接事件. 关键代码如下

// 源码位置: io.netty.channel.socket.nio.NioSocketChannel#doConnect



// 源码位置: io.netty.channel.nio.NioEventLoop#processSelectedKey(java.nio.channels.SelectionKey, io.netty.channel.nio.AbstractNioChannel)

总结: 此篇文件简单说了下Netty作为服务端和客户端的时候, IO线程一直在无限循环着, 傻傻地做着轮询IO事件, 处理IO事件, 执行任务这三件事.

本文分享自微信公众号 - Netty历险记(infuq217)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
zdd小小菜鸟 zdd小小菜鸟
2年前
Netty面试
Netty面试1.BIO、NIO和AIO的区别?BIO:tex一个连接一个线程,客户端有连接请求时服务器端就需要启动一个线程进行处理。线程开销大。伪异步IO:将请求连接放入线程池,一对多,但线程还是很宝贵的资源
Wesley13 Wesley13
3年前
BIO和NIO
BIO:同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。 NIO(事件驱动):同步非阻塞式IO,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动
Stella981 Stella981
3年前
Netty面试题
1.BIO、NIO和AIO的区别?BIO:一个连接一个线程,客户端有连接请求时服务器端就需要启动一个线程进行处理。线程开销大。伪异步IO:将请求连接放入线程池,一对多,但线程还是很宝贵的资源。NIO:一个请求一个线程,但客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处
Wesley13 Wesley13
3年前
Netty4.0学习笔记系列之一:Server与Client的通讯
本文是学习Netty的第一篇文章,主要对Netty的Server和Client间的通讯机制进行验证。Server与Client建立连接后,会执行以下的步骤:1、Client向Server发送消息:Areyouok?2、Server接收客户端发送的消息,并打印出来。3、Server端向客户端发送消息:Iamok!4、Client接收
Stella981 Stella981
3年前
Netty权威指南 第2章NIO 入门读书笔记
2.1传统的BIO编程采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理,处理完成之后,通过输出流返回应答给客户端,线程销毁。这就是典型的一请求一应答通信模型。如果不创建线程,还是在主线程中处理请求,则整个服务端是单线程处理能力,待第一个客户端请
Stella981 Stella981
3年前
Linux应急响应(二):捕捉短连接
0x00前言​短连接(shortconnnection)是相对于长连接而言的概念,指的是在数据传送过程中,只在需要发送数据时,才去建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。在系统维护中,一般很难去察觉,需要借助网络安全设备或者抓包分析,才能够去发现。0x01应急场景​
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这