<2021SC@SDUSC>netty常见编解码器(二)
作者:互联网
2021SC@SDUSC
文章目录
前言
在这一篇博客中,将会介绍netty的FixedLengthFrameDecoder类,实现了固定长度的解码,是解码器中最简单的一个,但是实用性不高,所以不常使用。
一、FiexedLengthFrameDecoder
package io.netty.handler.codec;
import static io.netty.util.internal.ObjectUtil.checkPositive;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import java.util.List;
public class FixedLengthFrameDecoder extends ByteToMessageDecoder {
private final int frameLength;
public FixedLengthFrameDecoder(int frameLength) {
checkPositive(frameLength, "frameLength");
this.frameLength = frameLength;
}
@Override
protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
Object decoded = decode(ctx, in);
if (decoded != null) {
out.add(decoded);
}
}
protected Object decode(
@SuppressWarnings("UnusedParameters") ChannelHandlerContext ctx, ByteBuf in) throws Exception {
if (in.readableBytes() < frameLength) {
return null;
} else {
return in.readRetainedSlice(frameLength);
}
}
}
二、分析
在FixedLengthFrameDescoder类中,只有一个构造函数,public FixedLengthFrameDecoder(int frameLength)
,要求传入一个int类型的变量,并将传入的参数赋给frameLength
,且因为frameLength
是final变量,在实例被创建后,不允许再去修改它。frameLength
代表每一个帧的字节大小,实际使用中,将受到的消息按照这个变量的大小,还原成原来的数据。
在该类中,有两个decode方法,分别是protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception
和protected Object decode( @SuppressWarnings("UnusedParameters") ChannelHandlerContext ctx, ByteBuf in) throws Exception
,其中,前一个decode方法是从父类继承来的,根据模板方法,在netty收到消息时,会调用到这个方法,而在第一个decode方法中,调用了第二个decode方法。在这里,简单分析第二个decode方法。
其实,在第二个decode方法中,就是对传入的bytebuf判断它的可读字节有没有大于等于frameLength
,即现在缓冲区中字节数量有没有可以构成一个帧,如果没有,就返回null,否则ByteBuf类的readRetainedSlice方法,将长度为frameLength的字节从缓冲区中读出,然后返回给调用该方法的地方。
三、使用
经过分析,可以看到,FixedLengthFrameDecoder类的实现较为简单,但是,因为它对数据的大小有严格的限制,所以很难有实际的应用。比如,在网络层协议中,数据的头部有一个Option可选项,因此头部的大小其实是不定长的,如果一定要采用FixedLengthFrameDecoder,那么它的frameLength必须大于等于有可能的最长帧的大小,这样,在传输实际长度小于这个值的帧时,必须使用填充数据,造成网络资源的浪费,而且,关于填充字符的选择,也有一些问题,比如,如果采用’\0’作为填充字符,但实际传输的有意义的数据中也包含了这个字符的情况,应该如何处理?
四、总结
在本篇博客中,简单地分析了netty提供的FixedLengthFrameDecoder类,这个类将收集到的消息按照长度划分成不同的等长的帧,从而解决了粘包半包的问题,但是,虽然它的实现很简单,但是,有较强的局限性,因此,不具有实用性。如果想要借助实现自己的协议,且不能保证数据的大小一致,不建议使用FixedLengthFramdeDecoder。
标签:netty,frameLength,2021SC,ctx,编解码器,FixedLengthFrameDecoder,decode,ByteBuf,SDUSC 来源: https://blog.csdn.net/vrpseva/article/details/121711059