2017-06-15 37 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