Netty的主要组件
Channel
Channel作为Netty网络通信的主体,可以看作是通讯的载体,主要有三个状态:打开、关闭、连接。
Channel主要的IO操作:读(read)、写(write)、连接(connect)、绑定(bind),均为异步,也就是说在调用如上方法后,并不保证IO操作完成,但会在IO操作成功、失败或取消后,生成相应的记录保存在一个凭证中并返回。
ChannelHandler
负责Channel中的逻辑处理,可针对性地拦截处理Channel负责的IO操作或事件,然后在它的ChannelPipeline中将其递交给下一个handler。ChannelHandler中有许多方法需要实现,一般通过继承ChannelHandlerAdapter来实现。
ChannelPipeline
Netty中,ChannelPipeline相当于ChannelHandler的容器,它们可用于拦截和处理channel事件,关系如下图:
ChannelPipeline相当于ChannelHandler的容器,channel事件消息在ChannelPipeline中传播流动,而ChannelHandler可以针对性地对事件进行拦截处理、传递、忽略或者终止。一个ChannelHandler会绑定一个ChannelHandlerContext对象,ChannelHandler会通过与其对应的Context对象和ChannelPipeline交互,比如向上或向下传递events,动态地修改ChannelPipeline,或者通过ChannelHandlerContext中的AttributeKeys存储与handler相关的信息。
Netty 中的拆包器
拆包这个工作,Netty 已经为大家备好了很多不同的拆包器。本着不重复发明轮子的原则,我们直接使用Netty现成的拆包器。
Netty 中的拆包器大致如下:
固定长度的拆包器 FixedLengthFrameDecoder
每个应用层数据包的都拆分成都是固定长度的大小,比如 1024字节。
这个显然不大适应在 Java 聊天程序 进行实际应用。
行拆包器 LineBasedFrameDecoder
每个应用层数据包,都以换行符作为分隔符,进行分割拆分。
这个显然不大适应在 Java 聊天程序 进行实际应用。
分隔符拆包器 DelimiterBasedFrameDecoder
每个应用层数据包,都通过自定义的分隔符,进行分割拆分。
这个版本,是LineBasedFrameDecoder 的通用版本,本质上是一样的。
这个显然不大适应在 Java 聊天程序 进行实际应用。
基于数据包长度的拆包器 LengthFieldBasedFrameDecoder
将应用层数据包的长度,作为接收端应用层数据包的拆分依据。按照应用层数据包的大小,拆包。这个拆包器,有一个要求,就是应用层协议中包含数据包的长度。
这个显然比较适和在 Java 聊天程序 进行实际应用。下面我们来应用这个拆分器。