开发者社区> 问答> 正文

Netty的Decoder模块阻塞问题:报错

尝试使用Netty接收TCP传输的消息,但是发现如果对象发送消息频率过高,就会出现Decorder中消息不再读取的情况。

服务端代码如下:

public class Server {
	private static Logger log = Logger.getLogger(Server.class);
	final static int REMOTE_PORT = 17650;
	
	@PostConstruct  
    public void bind() throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        try {
            serverBootstrap
                    .group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG,100)
                    .childOption(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(64, 1024, 65536))
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            //添加解码
                            socketChannel.pipeline().addLast(new Decoder());
                        }
                    });
            ChannelFuture channelFuture = serverBootstrap.bind(REMOTE_PORT).sync();
            channelFuture.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
    
}

 Decoder解码器摘自《Netty实战一书的例子》,如下:

public class Decoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
        int messageLength = in.readableBytes();
        if (messageLength>=4){
            out.add(in.readInt());
        }
        //打印日志
        System.out.println(in.isReadable());
        System.out.println("readerIndex:"+in.readerIndex());
        System.out.println("writerIndex:"+in.writerIndex());
        System.out.println("capacity:"+in.capacity());
        System.out.println("refcount:"+in.refCnt());
        System.out.println("isWritable:"+in.isWritable());
    }
}

阻塞时,打印的日志如下:

true
readerIndex:23536
writerIndex:23538
capacity:65536
refcount:1
isWritable:true

打印出上面这条日志以后,就再也收不到客户端发送的消息了

展开
收起
kun坤 2020-06-06 15:46:50 757 0
1 条回答
写回答
取消 提交回答
  • msg 没有release ?

    ######1、ByteToMessageDecoder正常情况下会自动release,只是不知道为什么不工作了 2、如果手动release的话会报错,因为这个类是把里面的msg当容器用,不停接收新消息,复制到这个msg里面。这一次release掉,下一个消息就进不来了######

    m

    ######

    请先了解粘包断包,你这样写,不管来多少个字节,每次收到网络字节数据的时候你都是读一个4字节的int,高频率下字节缓冲区不停的堆积字节,但你也只是简单的读取了4字节的int。缓冲区是有最大容量的,你如果不做消费缓冲区满了就会出现你这种情况了。

    ######打印messageLength有惊喜######

    哈哈,惊喜不断

    ######

    每次消息包接收很多字节,你却只解析4字节,剩下的还存在缓冲区, 一积累,缓冲区爆了

    ######

    解码写的有问题, buff 没清理

    2020-06-06 15:48:07
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载