Netty原始碼分析第6章(解碼器)---->第2節: 固定長度解碼器
阿新 • • 發佈:2019-01-01
Netty原始碼分析第六章: 解碼器
第二節: 固定長度解碼器
上一小節我們瞭解到, 解碼器需要繼承ByteToMessageDecoder, 並重寫decode方法, 將解析出來的物件放入集合中集合, ByteToMessageDecoder中可以將解析出來的物件向下進行傳播, 這一小節帶大家剖析一個最簡單的解碼器FixedLengthFrameDecoder, 從它入手瞭解碼器的相關原理
FixedLengthFrameDecoder是一個固定長度的解碼器, 功能就是根據固定長度, 擷取固定大小的位元組數進行解碼
看其類的定義:
public class FixedLengthFrameDecoder extends ByteToMessageDecoder {
//長度大小
private final int frameLength;
public FixedLengthFrameDecoder(int frameLength) {
if (frameLength <= 0) {
throw new IllegalArgumentException(
"frameLength must be a positive integer: " + frameLength);
}
//儲存當前frameLength
this.frameLength = frameLength;
}
@Override
protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
//通過ByteBuf去解碼.解碼到物件之後新增到out上
Object decoded = decode(ctx, in);
if (decoded != null) {
//將解析到byteBuf新增到物件裡面
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);
}
}
}
我們看到這個類繼承了ByteToMessageDecoder, 重寫了decode方法
這個類只有一個屬性叫frameLength, 並在構造方法中初始化了該屬性
再看decode方法, 在decode方法中又呼叫了自身另一個過載的decode方法進行解析, 解析出來之後將解析後的資料放在集合out中
再看過載的decode方法:
過載的decode方法中首先判斷累加器的位元組數是否小於固定長度, 如果小於固定長度則返回null, 代表不是一個完整的資料包, 直接返回null
如果大於等於固定長度, 則直接從累加器中擷取這個長度的數值
in.readRetainedSlice(frameLength) 會返回一個新的擷取後的ByteBuf, 並將原來的累加器讀指標後移frameLength個位元組
如果累計器中還有資料, 則會通過ByteToMessageDecoder中callDecode方法裡while迴圈的方式, 繼續進行解碼
這樣, 就是實現了固定長度的解碼工作