FrameDecoder是Netty Protocol Decode最关键的Decoder,几乎所有和协议解码相关的Decoder都继承自它,那到底解决了什么问题?为什么需要这样的一个部件呢?TCP的传输是基于流的,每个数据包都有可能被分片和然后重组,这时候我们就需要协议去界定一个数据包,通常来说用来方式来确定数据包的边界,一个是基于长度,简单一点就是规定数据包的长度,例如规定每个数据包的长度为100byte,FixedlengthFrameDecoder就是这样,可实际中我们的数据包并不都是固定长度,可以说是大小不一的情况更常见。怎么样解决这个问题呢?我们加一个长度属性的header,标示我们实际内容的大小,这就是LengthFieldBasedFrameDecoder。
回归正题,为什么需要FrameDecoder,来考虑两个极端的问题:
1. 假设我们一帧(数据包)的大小为100byte,然而socket的sendBuffer的大小只有50byte,server端的readbuffer的大小也是50byte。这就意味着我们读两次才能读完成一帧。
2.Netty的NioWorker(Poller)是有读写控制,每次只能读到制定大小的buffer,例如一帧的大小还是100byte,Poller读到1024k,然后触发message receive事件去处理,这样第11帧只能读到24byte,显然不是一完整的帧剩余的76byte需要在下一次poll中接收。
通过这两个问题我们发现,有时候为了读完整的一帧需要累积读多次,就像以上两种情况需要两次,我们不能读到数据就进行处理,我们得需要一个累积器,把分散的buffer累积到累积器中,再进行解码,这样就能避免一帧跨两个buffer。
还是看看代码吧
if (cumulation == null) {
// the cumulation buffer is not created yet so just pass the input to callDecode(...) method 第一次的时候,累积器还没有创建,这时先解码,然后把剩余的部分加到累积器中。如果每次input都变完整的解码成一帧,没有/剩余则不会创建累积器
callDecode(ctx, e.getChannel(), input, e.getRemoteAddress());
//如果有剩余放入累积
if (input.readable()) {
// seems like there is something readable left in the input buffer. So create the cumulation buffer and copy the input into it
(this.cumulation = newCumulationBuffer(ctx, input.readableBytes())).writeBytes(input);
}
} else {
assert cumulation.readable();
boolean fit = false;
int readable = input.readableBytes();
int writable = cumulation.writableBytes();
int w = writable - readable;
if (w < 0) {
int readerIndex = cumulation.readerIndex();
if (w + readerIndex >= 0) {
// the input will fit if we discard all read bytes, so do it
cumulation.discardReadBytes();
fit = true;
}
分享到:
相关推荐
《跟闪电侠学Netty:Netty即时聊天实战与底层原理》是一本深入浅出的Netty技术指南,旨在帮助读者掌握Netty框架,并利用它实现即时聊天应用,同时理解其底层工作原理。Netty是Java领域的一款高性能、异步事件驱动的...
Maven坐标:io.netty:netty-all:4.1.68.Final; 标签:netty、all、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...
Netty是一个开源的高性能、异步事件驱动的网络应用程序框架,专为开发可维护的高性能协议服务器和客户端而设计。它极大地简化了Java网络编程,尤其是对于TCP和UDP套接字,以及各种自定义二进制或基于文本的协议。在...
Maven坐标:io.netty:netty-common:4.1.65.Final; 标签:netty、common、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的...
Maven坐标:io.netty:netty-all:4.1.27.Final; 标签:netty、all、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...
读书笔记:netty案例集锦netty demonetty实战
读书笔记:Netty 权威指南读书笔记
Maven坐标:io.netty:netty-common:4.1.68.Final; 标签:netty、common、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码...
Netty是一个高性能、异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。在Java世界中,Netty因其易用性、灵活性以及强大的性能而备受推崇,广泛应用于各种分布式系统、微服务架构以及高...
读书笔记:Netty权威指南 笔记Note of The Definitive Guide
读书笔记:netty 权威指南2.0netty 5.0
读书笔记:Netty实战
读书笔记:netty 实战
读书笔记:netty权威指南
读书笔记:netty练习实战
读书笔记:netty实战示例
读书笔记:netty 权威指南
读书笔记:Netty实战学习