源码地址: GitHub
LineBasedFrameDecoder,FixedLengthFrameDecoder,DelimiterBasedFrameDecoder使用详解
TCP以流的形式进行数据传输,上层的应用协议为了对消息进行划分,往往采用如下的4种方式。
(1)消息长度固定,累计读到长度总和为定长len的报文后,就认为读取到了一个完整的消息;然后重新开始读取下一个“完整”的数据包;
(2)将回车换行符作为消息结束符,如ftp协议;
(3)将特殊的分隔符作为消息的结束标识,回车换行符j是一种特殊的分隔符;
(4)通过在消息头中定义的长度字段表示消息的总长度;
Netty对以上4种应用做了抽象,提供了4种解码器,有了解码器,码农们不用考虑TCP的粘包、拆包的问题了。
LineBasedFrameDecoder:依次编译bytebuf中的可读字符,判断看是否有“\n”或者“\r\n”,如果有,就以此位置为结束位置,从可读索引到结束位置区间的字节就组成了一行。它是以换行符为结束标志的解码器,支持携带结束符或者不携带结束符两种解码方式,同时支持单行的最大长度。如果连续读取到最大长度后,仍然没有发现换行符,就会抛出异常,同时忽略掉之前读到的异常码流。
public LineBasedFrameDecoder(final int maxLength) {
this(maxLength, true, false);
}
public LineBasedFrameDecoder(final int maxLength, final boolean stripDelimiter, final boolean failFast) {
this.maxLength = maxLength;
this.failFast = failFast;
this.stripDelimiter = stripDelimiter;
}
构造参数中maxLength为支持的最大长度,如果failFash为true , 则超过maxLength字符还未出现换行符,则会抛出异常。stripDelimiter 为true 会不携带换行符,如果为false则会携带结束符。
https://www.cnblogs.com/orange1438/archive/2015/12/08/5028697.html
FixedLengthFrameDecoder:是固定长度解码器,它能按照指定的长度对消息进行自动解码,开发者不需要考虑TCP的粘包等问题。利用FixedLengthFrameDecoder解码,无论一次性接收到多少的数据,他都会按照构造函数中设置的长度进行解码;如果是半包消息,FixedLengthFrameDecoder会缓存半包消息并等待下一个包,到达后进行拼包,直到读取完整的包。
DelimiterBasedFrameDecoder:是自定义的分隔符解码,构造函数的第一个参数表示单个消息的最大长度,当达到该长度后仍然没有查到分隔符,就抛出TooLongFrameException异常,防止由于异常码流缺失分隔符导致的内存溢出。