這兩個類通常一起使用來解決半包與粘包的問題
LengthFieldPrepender編碼器
作用:將當前發送消息的二進制字節長度,添加到緩衝區頭部;這樣消息就有了固定長度,長度存儲在緩衝頭中
構造方法
public LengthFieldPrepender(int lengthFieldLength, boolean lengthIncludesLengthFieldLength) {
this(lengthFieldLength, 0, lengthIncludesLengthFieldLength);
}
lengthFieldLength 長度字段長度
lengthIncludesLengthFieldLength 長度字段是否包含長度字段長度
聽起來繞口,舉個例子
new LengthFieldPrepender(4, false)
上面的意思是:我用四個字節長度去存儲當前發送消息的二進制字節長度,並且這四個字節不算在長度中。
如果發送的消息是“hello ,world”,二進制字節長度12byte,編碼後則緩衝頭部的4個字節存儲的是12
new LengthFieldPrepender(4, true)
上面的意思是:我用四個字節長度去存儲當前發送消息的二進制字節長度,並且這四個字節算在長度中。
如果發送的消息是“hello ,world”,二進制字節長度12byte,編碼後則緩衝頭部的的4個字節存儲的是12(消息字節)+4(頭部長度字節)
貼上netty權威指南
LengthFieldBasedFrameDecoder半包解碼器
如果消息是通過長度進行區分(LengthFieldPrepender)此解碼器可以處理粘包與半包問題
其構造方法如下
public LengthFieldBasedFrameDecoder(
int maxFrameLength,
int lengthFieldOffset, int lengthFieldLength,
int lengthAdjustment, int initialBytesToStrip) {
this(
maxFrameLength,
lengthFieldOffset, lengthFieldLength, lengthAdjustment,
initialBytesToStrip, true);
}
共有5個參數
maxFrameLength:消息最大長度,超過會報錯
lengthFieldOffset:長度字段偏移量
lengthFieldLength:長度字段長度
lengthAdjustment:要添加到長度字段值的補償值
initialBytesToStrip:從解碼幀中刪除的第一個字節數
如下代碼表示:消息頭只有一個長度字段表示消息長度,佔4個字節(從0到4,前兩個參數);在解碼的時候刪除消息長度的4個字節(從0到4,後兩個參數)只留下消息內容。
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)
如下代碼表示:消息頭只有一個長度字段表示消息長度,佔4個字節(從0到4,前兩個參數);在解碼的時候會把消息原封不動解碼,解碼後的消息包括消息頭長度字段和消息體(從0到0,表示不刪除任何字節,所以包含頭部的4個字節和消息體的字節數)。
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 0)