1. 程式人生 > >Netty原始碼分析第6章(解碼器)---->第2節: 固定長度解碼器

Netty原始碼分析第6章(解碼器)---->第2節: 固定長度解碼器

 

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迴圈的方式, 繼續進行解碼

這樣, 就是實現了固定長度的解碼工作