本文将解答如何accept(), 即新的客户端连接上来之后如何创建对应的socket
一 基本的编程模型
socket serverSocket = CreateServerSocket(); //创建服务端Socket
bind(serverSocket) // 绑定
listen(serverSocket) //监听
select(serverSocket) //1. IO 多路复用
if (serverSocket.canRead()){ //2. 如果有新的连接
Socket client = serverSocket.accept() //3.创建新的连接
}
以上是基本的服务端编程模型, 最核心的无外乎3个过程
1. 调用IO 多路复用
2. 判断处于监听状态的socket 是否有新的连接到来
3.创建新的连接
任何服务端编程都逃脱上述3个步骤,netty 自然也不能例外,下面我们就分析这个三个核心步骤,我先贴下时序图的结论,然后再论述过程
二 Netty 的accept()过程
本文依旧先说出结论,给出时序图,然后对着时序图来给出代码解析过程
NioEventLoop:run()
-->processSelectedKey()
--> unsafe.read()
--> doReadMessages()
unsafe.read() 有两个主要函数调用 1.doReadMessage(), 2.fireChannelRead()
public void read(){
doReadMessage();
pipeline.fireChannelRead();
}
下面来分析这两个主要过程
2.1 doReadMessage() 关键过程解析如下图
114 行通过JDC的channel 调用其accept()函数获得SocketChannel ch, 然后通过 当前的NioServerChannel, eventLoop, ch 创造一个新的NioSocketChannel
这里的childEventLoopGroup 就是workgroup, childEventLoopGroup().next() 则是从从线程池中选择一个NioEventLoop
2.2 fireChannelRead
继续往下跟
再往下 进入 ServerBootstrapAcceptor 的channelRead()