netty源码浅析--accept

本文详细解析了Netty中accept操作的处理流程。从Selector获取活跃SelectionKey开始,通过NioEventLoop处理网络事件,利用SelectedSelectionKeySet保存事件触发的key。分析了如何通过attachment获取ServerSocketChannel并调用processSelectedKey方法。最后介绍了如何通过ServerSocketChannel.accept创建新的NioSocketChannel。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        前面我们分析了netty线程启动和服务器bind的过程,接着我们要分析的是服务器accept的过程。

        我们先看一下java nio中是怎么处理accept这个操作的。我们截取java nio中的一个代码片段。
java nio accept
selector获取活跃key之后,然后会判断key是否是可accept的,如果是则执行accept操作。我们都知道netty是对java nio的封装,所以对netty的accept的分析也会从获取的活跃的key开始。

netty使用NioEventLoop来处理相应的网络事件。当有客户端connect请求,selector可以返回其对应的SelectionKey,然后对这些key进行相应的处理。(为了说明处理流程,省去与流程无关代码)
这里写图片描述
采用SelectedSelectionKeySet保存有事件发生的selectedKey。
1、SelectedSelectionKeySet内部使用两个大小为1024的SelectionKey数组keysA和keysB保存selectedKey。
2、把SelectedSelectionKeySet实例映射到selector的原生selectedKeys和publicSelectedKeys。

process
selector会一次性的取到所有活跃的(有事件触发的)key,通过for循环来遍历所有的key。
通过attachment()来获取注册在ServerSocketChannel的附件,其实附件就是ServerSocketChannel本身。如果是AbstractNioChannel的实例,则调用processSelectedKey()方法。

processSelectedkey
unsafe是实际操作网络I/O的类。类名字是unsafe,并不是说这个类是不安全的,而是从框架的角度上来说尽量不要使用unsafe进行网络操作。
方法内部会对感兴趣的操作进行判断,这里由于我们分析的accept操作,所以会调用unsafe的read方法。

该read方法是在NioMessageUnsafe类实现的。同样的为了说明主要逻辑,省略一些属性判断和设置的相关代码。
这里写图片描述
大家有没有想过,为什么accept方法会在一个叫read方法内部。不要忽略了 这段代码。

 if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {
      unsafe.read();          
}

也就是说,如果是accept和read操作都会调用read方法。然后在read方法内部进行判断。doReadMessages(readBuf) 可以认为是在判断accept操作还是read操作。

doreadmessage
1、javaChannel()方法返回ServerSocketChannel实例。
2、ServerSocketChannel.accept方法返回socketChannel 。
3、把 NioServerSocketChannel 和 socketChannel 封装成 NioSocketChannel,并缓存到readBuf。
在调用NioSocketChannel的构造方法时会自动将read操作设置成为该channel当前感兴趣的事件。
这里写图片描述

至此accept操作完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值