摘要:客户端客户端启动的常规代码如下用于接收客户端请求的线程池职责如下。注册对应的网络监听状态为到多路复用器。由多路复用器在现场中轮询个,处理连接结果。具体服务端与客户端如何通信,以及内存管理等方面的知识下一次再写。
欢迎关注公众号:【爱编程】
如果有需要后台回复2019赠送1T的学习资料哦!!
本文是基于Netty4.1.36进行分析
服务端
Netty服务端的启动代码基本都是如下:
private void start() throws Exception {
final EchoServerHandler serverHandler = new EchoServerHandler();
/**
* NioEventLoop并不是一个纯粹的I/O线程,它除了负责I/O的读写之外
* 创建了两个NioEventLoopGroup,
* 它们实际是两个独立的Reactor线程池。
* 一个用于接收客户端的TCP连接,
* 另一个用于处理I/O相关的读写操作,或者执行系统Task、定时任务Task等。
*/
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup childGroup = new NioEventLoopGroup();
try {
//ServerBootstrap负责初始化netty服务器,并且开始监听端口的socket请求
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, childGroup)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
// 为监听客户端read/write事件的Channel添加用户自定义的ChannelHandler
socketChannel.pipeline().addLast(serverHandler);
}
});
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully().sync();
childGroup.shutdownGracefully().sync();
}
}
从上图的代码可以总结为以下几个步骤:
1、创建ServerBootStrap实例
2、设置并绑定Reactor线程池:EventLoopGroup,EventLoop就是处理所有注册到本线程的Selector上面的Channel
3、设置并绑定服务端的channel
4、5、创建处理网络事件的ChannelPipeline和handler,网络时间以流的形式在其中流转,handler完成多数的功能定制:比如编解码 SSl安全认证
6、绑定并启动监听端口
7、当轮训到准备就绪的channel后,由Reactor线程:NioEventLoop执行pipline中的方法,最终调度并执行channelHandler
服务端创建时序图
ServerBootStrap引导启动服务端
它就是主要引导启动服务端,工作包括以下:
1.创建服务端Channel
2.初始化服务端Channel
3.将Channel注册到selector
4.端口绑定
1.创建服务端Channel
流程:
首先从用户代码的bind()其实就是AbstractBootstrap.bind(),然后通过反射工厂将用户通过b.channel(NioServerSocketChannel.class)传入的NioServerSocketChannel通过调用底层的jdk的SelectorProvider创建channel,同时也接着创建好对应的ChannelPipeline。
详情可以参考下图,自己去查看一下源码:
2.初始化服务端Channel
主要工作如下:
1)设置的option缓存到NioServerSocketChannelConfig里
2)设置的attr设置到channel里
3)保存配置的childOptions,配置的childAttrs 到ServerBootstrapAcceptor里
4)往NioSocketChannel的pipeline中添加一个ServerBootstrapAcceptor
主要的核心源码如下:
@Override
void init(Channel channel) throws Exception {
final Map, Object> options = options0();
synchronized (options) {
setChannelOptions(channel, options, logger);
}
final Map, Object> attrs = attrs0();
synchronized (attrs) {
for (Entry, Object> e: attrs.entrySet()) {
@SuppressWarnings("unchecked")
AttributeKey