最近一直在看netty,看完以后就想作点笔记。但是实在是太忙了,挤了还要几个晚上终于挤出来了java
上图是服务端的实例代码。大体的流程先梳理一遍。react
首先会执行 用于建立两个线程组,boosGroup用于接受外部链接,对
SelectionKey.OP_ACCEPT 感兴趣
数组
,workGroup用于处理io操做,内部,每当有新链接进来的时候boosGroup 都会把链接封装成一个channel 交给workGroup 去处理。异步
咱们再看 NioEventLoopGroup 的构造方法,一直点进去,实际上调用的 MultithreadEventExecutorGroup oop
能够看到 这两行代码实际就是建立两个包含 NioEventLoop 对象的数组。NioEventLoop对象咱们后面介绍。spa
ServerBootstrap 是一个辅助类,主要用于设置各类配置参数,.net
.group(bossGroup, workerGroup)
线程
就是上面咱们建立的两个线程组,bossGroup
的做用就是不断地accept到新的链接,将新的链接丢给workerGroup
来处理3d
.channel(NioServerSocketChannel.class)
netty
表示服务端启动的是nio相关的channel,channel在netty里面是一大核心概念,能够理解为一条channel就是一个链接或者一个服务端bind动作
.childHandler(new ChannelInitializer<SocketChannel>)
表示一条新的链接进来以后,该怎么处理
上面的几行代码都是作相应配置。
真正的关键在于bind方法
咱们一路点击进去。这个干了三件事 初始化,注册,绑定端口。
咱们先看 initAndRegister
总共三步,建立channel,初始化,注册。
1.建立 反射调用,这里的clazz是在中设置的,因此这里建立出的是NioServerSocketChannel
2.初始化
初始化只作了两件事
p.addLast()
向serverChannel的流水线处理器中加入了一个 ServerBootstrapAcceptor
,从名字上就能够看出来,这是一个接入器,专门接受新请求,把新的请求扔给某个事件循环器
3.注册
将该条channel
绑定到一个selector
上去,一个selector被一个reactor线程使用,后续该channel
的事件轮询,以及事件处理,异步task执行都是由此reactor线程来负责
如今咱们的channel
已经和reactor
线程绑定在一块儿了,如今就剩下最后一步了,完成端口的绑定。
netty经过异步线程的方式完成端口绑定,这段代码比较难找,最终会来到 io.netty.channel.DefaultChannelPipeline.HeadContext#bind
最终调到了jdk里面的bind方法,这行代码事后,正常状况下,就真正进行了端口的绑定。