Unsafe 简介
Unsafe接口实际上是Channel 接口的辅助接口,它不应被用户代码 直接调用,实际的I/O 读写操作者是由Unsafe接口负责完成的。
在netty中一个很核心的组件,封装了java底层的socket操作,作为连接netty和java 底层nio的重要桥梁。
Unsafe功能列表
方法名 | 返回值 | 功能说明 |
invoker() | ChannelHandlerInvoker | 返回默认使用的ChannelHandlerlnvoker |
localAddress() | SocketAddress | 返回本地绑定的Socket地址 |
remoteAddress() | SocketAddress | 返回通信对端Socket地址 |
register(ChannelPromise promise) | void | 注册Channel 到多路复用器上,一旦完成,通知channelFuture |
bind(SocketAddress localAddress,ChannelPromise promise) | void | 绑定指定的本地地址 localAddress到当前的Channel 上,一旦完成,通知channelFuture |
connect(SocketAddress remoteAddress,SocketAddress localAddress,ChannelPromise promise) | void | 绑定本地的 localAddress之后,连接服务端,一旦完成,通知channelFuture |
disconnect(ChannelPromise promise) | void | 断天Channel的连接。一旦完成,通知channelFuture |
close(ChannelPromise promise) | void | 关闭Channel的连接,一旦完成,通知channelFuture |
closcForcibly() | void | 强制立即关闭连接 |
beginRead() | void | 设置网络操作位为读用于读取信息 |
write(Object msg,ChannelPromise promise) | void | 发送消息,一但完成,通知ChannelFuture |
flush() | void | 将发送缓冲数组中的消息写入到Channel中 |
voidPromise() | ChannelPromise | 返回一个特殊的可重用和传递的ChannelPromise,它不用于操作成功或者失败的通知器,仅仅作为一容器被使用 |
outboundBuffer() | ChannelOutboundBuffer | 返回消息发送缓冲区 |
Unsafe继承关系类图
AbstractUnsafe 源码分析
register方法主要用于将当前Unsafe对应的Channel注册到EventLoop的多路复用器上,然后调用DefaultChannelPipeline的fireChannelRegisted方法,如果Channel被激活,则调用fireChannelActive方法。
bind方法主要用于绑定指定端口。对于服务端,用于绑定监听端口,并设置backlog参数;对于客户端,用于指定客户端Channel的本地绑定Socket地址
disconnect方法 该方法用于客户端或服务端主动关闭连接
close方法
-
确保在多线程环境下,多次调用close和一次调用的影响一致,并且可以通过promis得到同样的结果。
-
保证在执行close的过程中,不能向channel写数据。
-
调用doClose0执行执真正的close操作。
-
调用deregister对channel做最后的清理工作,并触发channelInactive, channelUnregistered事件。
write方法实际上是将消息添加到环形发送数组上,并不真正的写Channel(真正的写Channel是flush方法)
如果Channel 没有处于激活状态,说明TCP链路还有真正建立成功,当前Channel存在以下两种状态
(1)Channel 打开,但是TCP链路尚未建立成功
(2)Channel 已经关闭
flush方法
前面提到,write方法负责将消息放进发送缓冲区,并没有真正的发送,而flush方法就负责将发送缓冲区中待发送的消息全部写进Channel中并发送。
AbstractNioUnsafe源码分析
abstractNioUnsafe 是AbstractUnsafe类的NIO实现,它主要实现connect,finish|Connect 等方法
connect方法:首先获取当前的连接状态进行缓存,然后发起连接操作
socketChannel 执行connect()操作有三种可能的结果
(1)连接成功 返回true
(2)暂时没有连接上,服务端没有返回ACK应答,连接结果不确定,返回false;
(3)连接失败,直接抛出I/O异常
finishConect方法:
客户端接收到的服务端的TCP握手应答消息,通过SocketChannel 的finishConnect方法对连接结果进行判断。
socketChannel 执行finishConect()操作有三种可能的结果
(1)连接成功返回true
(2)连接失败返回false
(3)发生链接被关闭,链接中断等异常,连接失败。
NioByteUnsafe源码分析
NioByteUnsafe封装了NioSocketChannel读取底层数据的流程
NioByteUnsafe当中的read方法
1、分配ByteBuf。
2、从底层SocketChannel中读取字节,封装到ByteBuf中。
3、调用Channel的PPLine交给管道中的编解码器去处理。
4、调用各种事件。