Netty 提供了丰富的解码器抽象基类,主要分为两类:

  • 解码字节到消息(ByteToMessageDecoder 和 ReplayingDecoder)
  • 解码消息到消息(MessageToMessageDecoder)

一、ByteToMessageDecoder

  ByteToMessageDecoder 用于将字节转为信息(或其他字节序列)。方法如下:

  

  在下面的例子中,我们将实现从入站 ByteBuf 读取每个整数并将其传递给 pipeline 中的下一个 ChannalInboundHandler。流程如下:

  

  代码如下:

 /**
* 读取四字节,解码成整形
* 继承于 ByteToMessageDecoder
*
*/
public class ToIntegerDecoder extends ByteToMessageDecoder { @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if(in.readableBytes() >= 4) { // int是4字节
out.add(in.readInt()); // 添加到解码信息的List中
}
} }

  注意,一旦一个消息被编码或解码会自动调用 ReferenceCountUtil.release(message)。如果你稍后还需要用到这个引用,你可以调用 ReferenceCountUtil.retain(message)。

  

二、ReplayingDecoder

  上面的例子读取缓冲区的数据之前需要检查缓冲区是否有足够的字节,使用 ReplayingDecoder 就无需自己检查。若 ByteBuf 中有足够的字节,则会正常读取;若没有足够的字节则会停止解码。如下:

 /**
* 读取四字节,解码成整形
* 继承于ReplayingDecoder,不需要检查缓存区是否有足够的字节
*
*/
public class ToIntegerDecoder2 extends ReplayingDecoder<Void> { @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
out.add(in.readInt()); // 读取整形并添加到解码信息的List中
} }

三、MessageToMessageDecoder

  用于从一种消息解码为另一种消息(例如,POJO 到 POJO)。与上面类似,代码如下:

 /**
* 将整形解码为字符串
* 继承于MessageToMessageDecoder
*
*/
public class IntegerToStringDecoder extends MessageToMessageDecoder<Integer> { @Override
protected void decode(ChannelHandlerContext ctx, Integer msg, List<Object> out) throws Exception {
out.add(String.valueOf(msg)); // 将整形转换为字符串
} }

四、在解码中处理太大的帧

  Netty 是异步架构需要将缓冲区字节存在内存中,知道你能够解码它们。因此,你不能让你的解码器缓存太多的数据以免耗尽可用内存。下面为解决方案:

 /**
* 在解码时处理太大的帧
*
*/
public class SafeByteToMessageDecoder extends ByteToMessageDecoder {
private static final int MAX_FRAME_SIZE = 1024; @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
int readable = in.readableBytes();
if(readable > MAX_FRAME_SIZE) { // 缓冲区数据过大
in.skipBytes(readable); // 忽略所有可读的字节
// 抛出异常通知这个帧数据超长
throw new TooLongFrameException("帧数据超长");
}
// TODO 数据编码
} }

  这种保护很重要,尤其是当你编码一个有可变帧大小的协议的时候。

Netty入门(六)Decoder(解码器)的更多相关文章

  1. Netty学习(六)-LengthFieldBasedFrameDecoder解码器

    在TCP协议中我们知道当我们在接收消息时候,我们如何判断我们一次读取到的包就是整包消息呢,特别是对于使用了长连接和使用了非阻塞I/O的程序.上节我们也说了上层应用协议为了对消息进行区分一般采用4种方式 ...

  2. Netty入门

    一.NIO Netty框架底层是对NIO的高度封装,所以想要更好的学习Netty之前,应先了解下什么是NIO - NIO是non-blocking的简称,在jdk1.4 里提供的新api,他的他的特性 ...

  3. Netty入门(三)之web服务器

    Netty入门(三)之web服务器 阅读前请参考 Netty入门(一)之webSocket聊天室 Netty入门(二)之PC聊天室 有了前两篇的使用基础,学习本文也很简单!只需要在前两文的基础上稍微改 ...

  4. Netty入门(1) - 简介

    什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Tomcat和Netty有什么区别? Netty和Tom ...

  5. Netty入门教程——认识Netty

    什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Netty 是一个广泛使用的 Java 网络编程框架(N ...

  6. Netty入门与实战教程总结分享

    前言:都说Netty是Java程序员必须要掌握的一项技能,带着不止要知其然还要知其所以然的目的,在慕课上找了一个学习Netty源码的教程,看了几章后着实有点懵逼.虽然用过Netty,并且在自己的个人网 ...

  7. Netty(六)UDP在netty中的使用

    关于UDP的介绍,这里不在阐述.相比于TCP而言,UDP不存在客户端和服务端的实际链接,因此不需要为连接(ChannelPipeline)设置handler. 服务端: public void run ...

  8. Netty入门之客户端与服务端通信(二)

    Netty入门之客户端与服务端通信(二) 一.简介 在上一篇博文中笔者写了关于Netty入门级的Hello World程序.书接上回,本博文是关于客户端与服务端的通信,感觉也没什么好说的了,直接上代码 ...

  9. 脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?

    本文引用了“帅地”发表于公众号苦逼的码农的技术分享. 1.引言 搞网络通信应用开发的程序员,可能会经常听到外网IP(即互联网IP地址)和内网IP(即局域网IP地址),但他们的区别是什么?又有什么关系呢 ...

  10. netty入门(一)

    1. netty入门(一) 1.1. 传统socket编程 在任何时候都可能有大量的线程处于休眠状态,只是等待输入或者输出数据就绪,这可能算是一种资源浪费. 需要为每个线程的调用栈都分配内存,其默认值 ...

随机推荐

  1. Iframe 父页面自动获取子页面的高度

    <iframe id="mainweb" name="mainweb" src="http://www.baidu.com/" bor ...

  2. winform窗体 小程序【进程】

    进程 一个应用程序就是一个进程,我的理解是,只要是打开应用程序,就会创建进程. 在.NET框架在using.System.Diagnostics名称空间中,有一个类Process,用来创建一个新的进程 ...

  3. 导航栏pop拦截

    一.新建一个分类 二.导入分类头文件 三.需要拦截的地方实现方法   - (BOOL)navigationShouldPopTwo  即可 .h #import <UIKit/UIKit.h&g ...

  4. A simple problem(hdu2522)

      A simple problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  5. 取石子游戏(hdu1527 博弈)

    取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  6. 步步深入MySQL:架构->查询执行流程->SQL解析顺序!

    一.前言 一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇博文了. 本文将从MySQL总体架构--->查询执行流程--->语句执行顺序 ...

  7. 实例化Flask的参数 及 对app的配置

    Flask 是一个非常灵活且短小精干的web框架 , 那么灵活性从什么地方体现呢? 有一个神奇的东西叫 Flask配置 , 这个东西怎么用呢? 它能给我们带来怎么样的方便呢? 首先展示一下: from ...

  8. python-命令模式

    源码地址:https://github.com/weilanhanf/PythonDesignPatterns 说明: 命令在发送方被激活,而在接收方被响应.一个对象既可以作为命令的发送方,也可以作为 ...

  9. JSON 解析工具的封装(FastJSON-->Java)

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.添加依赖包 <dependency> <groupId>com.alibaba< ...

  10. 2016计蒜之道复赛 百度地图的实时路况(Floyd 分治)

    题意 题目链接 Sol 首先一个结论:floyd算法的正确性与最外层\(k\)的顺序无关(只要保证是排列即可) 我大概想到一种证明方式就是把最短路树上的链拿出来,不论怎样枚举都会合并其中的两段,所以正 ...