Netty学习(三)—Codec编解码基础

Netty学习(三)—Codec编解码基础

Codec框架无论是decoder还是encoder本质上都是ChannelHandler处理器,用来将字节转换成基本数据类型或者将基本数据类型转换成字节;

个人主页:tuzhenyu’s page
原文地址:Netty学习(三)—Codec编解码基础

解码器

  • 解码器用来将输入数据流按照特定的格式转换成目标程序格式,解码器的基础类包括ByteToMessageDecoder和MessageToMessageDecoder两种,这两个类都继承了ChannelInboundHandlerAdapter类,实现了自定义的ChannelRead()方法用于对输入字节流进行处理;

  • 用户自定义特定作用的解码器都需继承ByteToMessageDecoder或MessageToMessageDecoder,实现其自定的解码方法decode()即可;

  • ByteToMessageDecoder和MessageToMessageDecoder区别:

    • ByteToMessageDecoder解码基类用于将特定数量的字节转换成特定格式的消息,比如LineBasedFrameDecoder,DelimiterBasedFrameDecoder,FixedLengthFrameDecoder和LengthFieldBasedFrameDecoder等都是继承ByteToMessageDecoder基类,实现其decode()方法;

    • MessageToMessageDecoder解码基类是用来将一个消息类型转换成另外一种消息格式,例如StringDecoder继承MessageToMessageDecoder将字节类型转换成字符类型;

ByteToMessageDecoder解码基类

  • ByteToMessageDecoder继承了ChannelInboundHandlerAdapter,实现了ChannelRead()方法
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    if (msg instanceof ByteBuf) {
        CodecOutputList out = CodecOutputList.newInstance();
        try {
            ByteBuf data = (ByteBuf) msg;
            first = cumulation == null;
            if (first) {
                cumulation = data;
            } else {
                cumulation = cumulator.cumulate(ctx.alloc(), cumulation, data);
            }
            callDecode(ctx, cumulation, out);
        } catch (DecoderException e) {
            throw e;
        } catch (Throwable t) {
            throw new DecoderException(t);
        } finally {
            if (cumulation != null && !cumulation.isReadable()) {
                numReads = 0;
                cumulation.release();
                cumulation = null;
            } else if (++ numReads >= discardAfterReads) {
                // We did enough reads already try to discard some bytes so we not risk to see a OOME.
                // See https://github.com/netty/netty/issues/4275
                numReads = 0;
                discardSomeReadBytes();
            }

            int size = out.size();
            decodeWasNull = !out.insertSinceRecycled();
            fireChannelRead(ctx, out, size);
            out.recycle();
        }
    } else {
        ctx.fireChannelRead(msg);
    }
}
  • 在ChannelRead()中将数据流读入到ByteBuf中,调用自定义实现的decode()方法对ByteBuf进行处理;
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值