请问,Netty是如何把连接转换为Channel的?

juedui0769
  • 97
  • 最近在阅读 Netty 的源码,但是有个地方一直没搞懂,
  • 服务端启动类 ServerBootstrap.java 中有个嵌套类 ServerBootstrapAcceptor,它的 channelRead(ctx, msg) 方法可以直接将 Object msg 强转为 Channel 对象。
  • 在调用 channelRead(ctx, msg) 方法之前,Netty 是在什么地方将客户端的连接转换为 Channel 的呢?有点头疼!
  • 下图是ServerBootstrapAcceptor源代码截图,使用的Netty版本是 netty-all:4.1.15.Final

图片描述

回复
阅读 1.8k
1 个回答
juedui0769
  • 97

2019年3月24日18:58:36

  • 问题是我提的,这个问题困扰我很久了,之前对 Netty 各组件不熟悉,只能先看书、看视频慢慢理解;前两天又一次看到代码ServerBootstrap.ServerBootstrapAcceptor#channelRead(ctx, msg) 还是很晕,遂发帖提问。自己也在思索,寻找答案!就在发布问答之后的几个小时之后,我想到一种解题思路,现列举如下(仔细编写提问,有时也能帮助找到答案):
  • 我是用 IntelliJ IDEAFind Usages 找到调用关系的。(很惭愧,阅读源码不多,所以之前一直没使用 Find Usages 这个功能来辅助摸清调用关系)

图片描述

  • 如上图,最关键的一处调用就是 processSelectedKey(k, ch) 方法了,这个方法的命名也能够说明问题,它是用来处理SelectionKey的,
  • NioEventLoopprocessSelectedKey(SelectionKey k, AbstractNioChannel ch) 方法中有对 java.nio 的 SelectionKeyOP_CONNECT, OP_WRITE, OP_READ, OP_ACCEPT 的判断
  • 看到这里,我基本就明白了。找到了对 OP_ACCEPT 的处理,就找到了对客户端连接的处理了,SocketChannel 就在随后的代码中创建出来的(一个SocketChannel就对应一个与客户端的连接!)。
  • NioEventLoop#processSelectedKey(k, ch)方法中调用了unsafe#read(),这里的unsafe对应的是AbstractNioMessageChannel的内部类NioMessageUnsafe,在NioMessageUnsafe#read()方法内部又调用了NioServerSocketChanneldoReadMessages(buf:List)方法,就是在这里SocketChannel被创建。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏