博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Netty笔记:FrameDecoder
阅读量:4214 次
发布时间:2019-05-26

本文共 1886 字,大约阅读时间需要 6 分钟。

     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;                }
 

转载地址:http://uqdmi.baihongyu.com/

你可能感兴趣的文章
判断有向图图是否有环
查看>>
基于队列的拓扑排序
查看>>
基于DFS的拓扑排序
查看>>
CSP 2016_4_4 游戏
查看>>
hdoj 1875 畅通工程再续 Prim / kruscal
查看>>
csp 2016_4_3 路径解析
查看>>
优先队列优化的 Dijkstra算法
查看>>
SPFA算法
查看>>
拓扑排序+最短路径(无环加权有向图最短路径算法)
查看>>
无环有向图最长路径
查看>>
Bellman_ford 边表示
查看>>
hdoj 1010 DFS +减枝
查看>>
hdoj 1595 最短路中的最长路(good)
查看>>
C++优先队列使用
查看>>
hdoj 1026
查看>>
csp 2017_3_3 markdown
查看>>
CSP 2017_9_4 通信网络
查看>>
hdoj 1026 搜索
查看>>
递归 理解
查看>>
欧几里德求最大公约数/最小公倍数
查看>>