2017-06-15 36 views
1

我正在擴展ChannelInboundHandlerAdapter並且想要讀取確切的字節數。Netty讀取確切字節數

public class Reader extends ChannelInboundHandlerAdapter{ 

    @Override 
    public void channelRead(ChannelHandlerContext ctx, Object msg){ 
     ByteBuf b = (ByteBuf) msg; 
     byte size = b.readByte(); 
     //Now I want to read exactly size bytes from the channel 
     //and then again read the number of bytes and read the bytes... 
    } 

} 

問題是可能發生這種情況,我們從ByteBuf讀取少於所需的字節。如何閱讀更多Channel

回答

1

僅供閱讀,您可以使用b.readSlice(size)。然而,正如您所提到的,緩衝區可能沒有足夠的數據來處理您的消息。所以你需要在創建消息之前充分使用數據。對於這種情況,我建議您使用內置的ByteToMessageDecoder處理程序。它會爲你處理低級字節。因此,與ByteToMessageDecoder你的代碼看起來就像這樣:

class Reader extends ByteToMessageDecoder { 
    @Override 
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { 
     byte size = in.readByte(); 
     if (in.readableBytes() < size) { 
      in.resetReaderIndex(); 
      return; 
     } 

     ByteBuf bb = in.readSlice(size); 
     //make whatever you want with bb 
     Message message = ...; 
     out.add(message); 
    } 
} 

所以在這個例子,你看你需要閱讀該消息的字節數 - size。然後你檢查你的in緩衝區是否有足夠的數據要消耗。如果沒有 - 您將控制返回到ByteToMessageDecoder,直到它讀取更多。並重復,直到你有足夠的數據來構建你的消息。

+0

其實,是的。非常感謝。但是'ReplayingDecoder'之間的區別呢?何時使用哪一個? –

+1

@ St.Antario請看'ReplayingDecoder' javadocs。用例子有很好的解釋。簡單地說''ReplayingDecoder'做的更多,你不需要檢查'in.readableBytes()

+0

ReplayingDecoder可以幫助您處理底層流數據的複雜情況,例如數據不夠。如果你不關心性能,它會太多地減少你的代碼邏輯複雜性。 – Kaneg