Netty入门(六)Decoder(解码器)

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

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

一、ByteToMessageDecoder

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

  

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

  

  代码如下:

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

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

  

二、ReplayingDecoder

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

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

三、MessageToMessageDecoder

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

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

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

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

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

原文地址:https://www.cnblogs.com/coderJiebao/p/Netty06.html

时间: 2024-09-30 20:55:07

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

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

Netty入门之客户端与服务端通信(二) 一.简介 在上一篇博文中笔者写了关于Netty入门级的Hello World程序.书接上回,本博文是关于客户端与服务端的通信,感觉也没什么好说的了,直接上代码吧. 二.客户端与服务端的通信 2.1 服务端启动程序 public class MyServer { public static void main(String[] args) throws InterruptedException { EventLoopGroup bossGroup = ne

Netty(六)UDP在netty中的使用

关于UDP的介绍,这里不在阐述.相比于TCP而言,UDP不存在客户端和服务端的实际链接,因此不需要为连接(ChannelPipeline)设置handler. 服务端: 1 public void run(int port)throws Exception{ 2 EventLoopGroup group = new NioEventLoopGroup(); 3 try { 4 Bootstrap b = new Bootstrap(); 5 b.group(group).channel(NioD

网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门

1.前言 即时通讯网整理了大量的网络编程类基础文章和资料,包括<TCP/IP协议 卷1>.<[通俗易懂]深入理解TCP协议>系列.<网络编程懒人入门>系列.<不为人知的网络编程>系列.<P2P技术详解>系列.<高性能网络编程>系列.甚至还有图文并貌+实战代码的<NIO框架入门>等,目的是帮助即时通讯类应用的开发者,至少要掌握网络编程最基本的原理,所谓知其然更要知其所以然.尤其现在移动网络大行其道的时代,在网络环境如此复杂的

Netty入门二:开发第一个Netty应用程序

    既然是入门,那我们就在这里写一个简单的Demo,客户端发送一个字符串到服务器端,服务器端接收字符串后再发送回客户端. 2.1.配置开发环境 1.安装JDK 2.去官网下载jar包 (或者通过pom构建) 2.2.认识下Netty的Client和Server 一个Netty应用模型,如下图所示,但需要明白一点的是,我们写的Server会自动处理多客户端请求,理论上讲,处理并发的能力决定于我们的系统配置及JDK的极限. Client连接到Server端 建立链接发送/接收数据 Server端

Python爬虫入门六之Cookie的使用

大家好哈,上一节我们研究了一下爬虫的异常处理问题,那么接下来我们一起来看一下Cookie的使用. 为什么要使用Cookie呢? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密) 比如说有些网站需要登录后才能访问某个页面,在登录之前,你想抓取某个页面内容是不允许的.那么我们可以利用Urllib2库保存我们登录的Cookie,然后再抓取其他页面就达到目的了. 在此之前呢,我们必须先介绍一个opener的概念. 1.Opener 当你获取一个

DevExpress XtraReports 入门六 控件以程序方式创建一个 交叉表 报表

原文:DevExpress XtraReports 入门六 控件以程序方式创建一个 交叉表 报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用的,为了帮助更多的人不会像我这样浪费时间才写的这篇文章,高手不想的看请路过 本文内容来DevExpress XtraReports帮助文档,如看过类似的请略过. 废话少说 开始正事 在继续本示例之前,要把所有 必需的程序集 添加到项目的 引用 列表中,并且把一个按钮拖放到窗体上. 然后,以下列方式接管此按钮的

[WebGL入门]六,顶点和多边形

注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正. 可以在三维空间中描画的东西 要说在WebGL的世界里能够描画什么,其实任何东西都可以描画.而描画的最基本的东西就是下面几种. ?点 ?线段 ?三角形 虽然在OpenGL中提供了矩形的绘制,但是WebGL中基本上只能绘制上面的三种类型.和二维世界不同,比如像HTML中的img标签那样,简单的在画

netty入门实例

TimeServer.java package netty.timeserver.server; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGro

Perl入门(六) Perl方法的使用

 1.定义一个方法 Perl使用sub定义方法. 语法: sub 方法名称{方法体} 2.调用一个方法 Perl直接使用方法名称调用方法. 调用方式有以下四种: 方法名称: &方法名称: 方法名称(); &方法名称(); 说明:方法调用可以再任何位置,可以在方法前.后调用,也可以在方法体内部调用. 3.传递参数 Perl通过方法名后面的括号将参数列表传递到方法体内.例如:function_name("param1","param2"...); 方

AppleWatch开发入门六——Glance(预览)扩展的应用

AppleWatch开发入门六--Glance(预览)扩展的应用 一.简介 Glance是watchOS中类似iOS的today插件一样的预览扩展.提供了Glance功能的WatchApp可以在手表主页上唤起Glance,展示app相关信息,然而这个扩展只能作为展示作用,并不能进行太多的交互,界面的布局也有很大的限制,因此,Glance的应用主要在于展示备忘信息等.特点如下: 1.扩展的样式布局我们并不能完全个性化,只能通过系统模板来布局. 2.扩展中不能添加交互功能,只能展示信息,点击界面间唤