手把手教你调试Netty创建连接流程源码

举报
JavaEdge 发表于 2021/06/04 00:29:25 2021/06/04
【摘要】 执行过程 boss thread NioEventLoop 中的 selector轮询创建连接事件 (ОР_АССЕРT)创建 socket channel初始化 socket channel 并从 worker group 中选择一个 NioEventLoop worker thread 将socket channel注册到选择的NioEventLoop的se...

执行过程

boss thread

  • NioEventLoop 中的 selector轮询创建连接事件 (ОР_АССЕРT)
  • 创建 socket channel
  • 初始化 socket channel 并从 worker group 中选择一个 NioEventLoop

worker thread

  • 将socket channel注册到选择的NioEventLoop的selector
  • 注册读事件(OP_ READ)到selector 上

接收连接请求的处理本质是对 OP_ACCEPT 的处理,即在 NioEventLoop 中,因为注册到了NioEventLoop的 selector。
分别调试启动 EchoServer 和 EchoClient

  • 跳至对应 handler

    • 当前为 bosseventloop,不是 workereventloop
  • 所以这里 false,又来到注册

  • 创建完连接后了,已经可以开始接收数据了,即准备读数据了

    最后观察下 server 的日志信息

  • 前5行都是服务启动,后面的就是为了创建连接

  • 服务启动过程多了个 bind 过程,且只绑定了一个接口,而对于下面的创建连接过程它有两个端口:客户端端口+server 监听的端口,这就是 socketChannel

接收连接的核心代码

// 阻塞轮询。非阻塞轮询。超时等待轮询
selector.select()/ selectNow()/select(timeoutMillis) 发现 OP_ACCEPT 事件,处理:
SocketChannel socketChannel = serverSocketChannel.accept()
selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);
selectionKey.interestOps(OP_READ);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

创建连接的初始化和注册是通过pipeline.fireChannelReadServerBootstrapAcceptor中完成

第一次Register并非监听OP_READ,而是0

selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this)

  
 
  • 1

最终监听OP_READ是通过"Register"完成后的fireChannelActive
(io.netty.channel.AbstractChannel.AbstractUnsafe#register0)触发

Worker’s NioEventLoop是通过Register操作执行来启动。

接受连接的读操作,不会尝试读取更多次(16次)。
因为无法知道后续是否还有连接,不可能一直尝试。

文章来源: javaedge.blog.csdn.net,作者:JavaEdge.,版权归原作者所有,如需转载,请联系作者。

原文链接:javaedge.blog.csdn.net/article/details/111567550

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。