netty中的报文分割符

分析常用的两个FrameDecoder,LineBasedFrameDecoder和DelimiterBasedFrameDecoder

这两个都是extends ByteToMessageDecoder,如LineBasedFrameDecoder的属性:

 /** Maximum length of a frame we're willing to decode.  */
    private final int maxLength;
    /** Whether or not to throw an exception as soon as we exceed maxLength. */
    private final boolean failFast;
    private final boolean stripDelimiter;
    /** True if we're discarding input because we're already over maxLength.  */
    private boolean discarding;
    private int discardedBytes;
    /** Last scan position. */
    private int offset;

new LineBasedFrameDecoder(10000,true,true),第二个参数是stripDelimiter,第三个参数是failFast,顾名思义,第二个参数是最终报文去掉分割符,第三个参数是快速失败。下面测试一下第三个参数。

 .childHandler(new ChannelInitializer<SocketChannel>() { // (4)
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline()
                     .addLast("frameDecoder", new LineBasedFrameDecoder(100,true,true))  //new LineBasedFrameDecoder(100))
                     .addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8))
                     .addLast("stringEncoder", new StringEncoder(CharsetUtil.UTF_8))
                     .addLast("messageHandler",new LineEchoHandler());
                 }
             })

首先是new LineBasedFrameDecoder(10000)),这时候客户端发送一个大报文2951,远超过了100,如果failfast是false,这个分割器会把2951这个报文全部读取,但是,一旦决定丢弃,只会记录要丢弃的长度,不会持有内容,所以就算遇到超长的报文,也不会占据内存。

现在有另一个疑问,如果failfast为true,会怎么样?

如果是

new LineBasedFrameDecoder(100,true,true),那么这个报文依然会被全部丢弃,只是会快速的抛出异常,而且,如果抛出异常但是不关闭连接的话,会多次读取将这个有问题的报文丢弃掉,做到不影响下一帧报文。

注意读取大报文的时候,netty并不是一开始就分配一个很大的directbuffer,而是从小到大逐步递增。

AbstractNioByteChannel.read()方法中,会使用allocHandle.allocate(allocator)分配一个bytebuf,如果这个bytebuf在这次读取中不够用,会增大进行下次读取。读取完成后还会记录这次读取的字节数目,以便扩充的时候决定扩充多大。

转载于:https://my.oschina.net/wuxiaofei/blog/1612738

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值