Netty Decoder:ByteToMessageDecoder
1. ByteToMessageDecoder
这个类是解码器的基类,其中描述了解码器基本的工作方式和实现原理;;还定义了一个解码的抽象方法decode,这个方法由业务实现,负责将一段字节数据解码为具体的消息对象。
    // 存储接收到的数据
    ByteBuf cumulation;
    private boolean first;
    @Override
    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) {
                    // 如果 ByteBuf 为空,则将 ByteBuf 指向接收到的消息
                    cumulation = data;
                } else {
                    // 如果 ByteBuf 不为空,则将接收到的数据追加到 ByteBuf
                    cumulation = cumulator.cumulate(ctx.alloc(), cumulation, data);
                }
                // 解码 ByteBuf 中的数据
                callDecode(ctx, cumulation, out);
            } catch (DecoderException e) {
                throw e;
            } catch (Throwable t) {
                throw new DecoderException(t);
            } finally {
                // ByteBuf 中的数据被消费完后,重置消费次数,释放内存,ByteBuf置为null
                if (cumulation != null && !cumulation.isReadable()) {
                    numReads = 0;
                    cumulation.release();
                    cumulation = null;
                    // ByteBuf 被消费16后压缩消息
                } else if (++ numReads >= discardAfterReads) {
                    numReads = 0;
                    discardSomeReadBytes();
                }
                // 将解码得到的报文对象全部分发下去
                int size = out.size();
                decodeWasNull = !out.insertSinceRecycled();
                fireChannelRead(ctx, out, size);
                out.recycle();
            }
        } else {
            ctx.fireChannelRead(msg);
        }
    }
       // 解码 ByteBuf
       protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
        try {
            // 如果 ByteBuf 有可读数据就继续解码
            while (in.isReadable()) {
                // 如果 out 中有内容,则将内容分发出去,然后清空 out, 并将 outSize 置为 0
                int outSize = out.size();
                if (outSize > 0) {
                    // 将 out 中的所有消息分发出去
                    fireChannelRead(ctx, out, outSize);
                    // out 存储解码后的报文对象
                    // 清空容器()
                    out.clear();
                    if (ctx.isRemoved()) {
                        break;
                    }
                    outSize = 0;
                }
                // 解码之前的可读长度
                int oldInputLength = in.readableBytes();
                // 调用自定义的解码器
                decode(ctx, in, out);
                if (ctx.isRemoved()) {
                    break;
                }
                // 由上面可知,outSize 为0 ,
                // 没有读取数据,没有得到消息对象,则跳出循环
                if (outSize == out.size()) {
                    if (oldInputLength == in.readableBytes()) {
                        break;
                    } else {
                        continue;
                    }
                }
                // 没有读取数据,却得到自定义的消息对象,抛出异常
                if (oldInputLength == in.readableBytes()) {
                    throw new DecoderException(
                            StringUtil.simpleClassName(getClass()) +
                            ".decode() did not read anything but decoded a message.");
                }
                if (isSingleDecode()) {
                    break;
                }
            }
        } catch (DecoderException e) {
            throw e;
        } catch (Throwable cause) {
            throw new DecoderException(cause);
        }
    }
Netty Decoder:ByteToMessageDecoder的更多相关文章
- Netty(二):如何处理io请求?
		
文接上一篇.上篇讲到netty暴露一个端口出来,acceptor, handler, pipeline, eventloop 都已准备好.但是并没体现其如何处理接入新的网络请求,今天我们就一起来看看吧 ...
 - 网络编程Netty入门:Netty的启动过程分析
		
目录 Netty的启动过程 Bootstrap 服务端的启动 客户端的启动 TCP粘包.拆包 图示 简单的例子 Netty编解码框架 Netty解码器 ByteToMessageDecoder实现类 ...
 - Netty(一):server启动流程解析
		
netty作为一个被广泛应用的通信框架,有必要我们多了解一点. 实际上netty的几个重要的技术亮点: 1. reactor的线程模型; 2. 安全有效的nio非阻塞io模型应用; 3. pipeli ...
 - Netty学习:ChannelHandler执行顺序详解,附源码分析
		
近日学习Netty,在看书和实践的时候对于书上只言片语的那些话不是十分懂,导致尝试写例子的时候遭遇各种不顺,比如decoder和encoder还有HttpObjectAggregator的添加顺序,研 ...
 - 自定义Decoder继承ByteToMessageDecoder实现解码的小案例
		
ByteToMessageDecoder是一种ChannelInboundHandler,可以称为解码器,负责将byte字节流(ByteBuf)转换成一种Message,Message是应用可以自己定 ...
 - netty学习:UDP服务器与Spring整合(2)
		
上一篇文章中,介绍了netty实现UDP服务器的栗子. 本文将会对UDP服务器与spring boot整合起来,并使用RedisTemplate的操作类访问Redis和使用Spring DATA JP ...
 - netty学习:UDP服务器与Spring整合
		
最近接到一个关于写UDP服务器的任务,然后去netty官网下载了netty的jar包(netty-4.0.49.Final.tar.bz2),解压后,可以看到上面有不少example,找到其中的关于U ...
 - Netty实战:设计一个IM框架
		
来源:逅弈逐码 bitchat 是一个基于 Netty 的 IM 即时通讯框架 项目地址:https://github.com/all4you/bitchat 快速开始 bitchat-example ...
 - Netty(一):的入门使用。
		
Netty的入门基本使用流程代码,不做具体分析.使用版本为Netty 4.x版本. 服务端调用示例: 绑定端口号为8080端口 package com.cllover; import com.sun. ...
 
随机推荐
- mac sublime3 无法安装Package Control
			
一.在线安装 1.打开sublime,Ctrl+` 打开控制台, 输入 import urllib.request,os,hashlib; h = '6f4c264a24d933ce70df5dedc ...
 - Numpy 线性代数
			
Numpy 提供了线性代数库 linalg , 该库包含了线性代数所需的所有功能,可以看卡下面的说明: 函数 描述 dot 两个数组的点积, 即元素对应相乘 vdot 两个向量的点积 inner 两个 ...
 - JavaSE 集合类HashSet保证自定义对象唯一性
			
首先我们自定义Person类,只有姓名和年龄两个属性 class Person{ private String name ; private int age ; public Person(Strin ...
 - ACM(图论)——tarjan算法详解
			
---恢复内容开始--- tarjan算法介绍: 一种由Robert Tarjan提出的求解有向图强连通分量的线性时间的算法.通过变形,其亦可以求解无向图问题 桥: 割点: 连通分量: 适用问题: 求 ...
 - SQL 语句中 where 条件后 写上1=1  的意思
			
这段代码应该是由程序(例如Java)中生成的,where条件中 1=1 之后的条件是通过 if 块动态变化的.例如: String sql="select * from table_nam ...
 - 根据缺少的so,安装相关的软件
			
http://blog.csdn.net/dianyueneo/article/details/8161350. ubuntu缺少libGL.so sudo apt-get install apt-f ...
 - MySql添加远程超级管理员用户
			
可以通过发出GRANT语句增加新用户:首先在数据库本机上用ROOT用户登录上MySql,然后运行命令: mysql>GRANT ALL PRIVILEGES ON *.* TO admin'@' ...
 - 使用kbmmw中的随机数替换delphi 10.3 自带的随机数
			
我们在开发中经常会使用随机数模拟各种随机条件,例如生成唯一的密码和令牌. 在计算机中,一般采用PRNG(伪随机序列发生器)模拟真实随机数.既然是随机,就要要没有任何规律, 在取值范围内均匀.独立.以确 ...
 - python -----一个简单的小程序(监控电脑内存,cpu,硬盘)
			
一个简单的小程序 用函数实现!~~ 实现: cpu 使用率大于百分之50 时 , C 盘容量不足5 G 时, 内存 低于2G 时. 出现以上其中一种情况,发送自动报警邮件! 主要运用 到了两个 模 ...
 - spring学习(二)---依赖注入
			
spring第二个特性是依赖注入. 学习依赖注入,首先应该明白两个问题:1,谁依赖谁:2,谁注入,注入什么? 首先还是看代码: 还是这个bean: package testSpring.busines ...