Netty入门(六)Decoder(解码器)
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(解码器)的更多相关文章
- Netty学习(六)-LengthFieldBasedFrameDecoder解码器
在TCP协议中我们知道当我们在接收消息时候,我们如何判断我们一次读取到的包就是整包消息呢,特别是对于使用了长连接和使用了非阻塞I/O的程序.上节我们也说了上层应用协议为了对消息进行区分一般采用4种方式 ...
- Netty入门
一.NIO Netty框架底层是对NIO的高度封装,所以想要更好的学习Netty之前,应先了解下什么是NIO - NIO是non-blocking的简称,在jdk1.4 里提供的新api,他的他的特性 ...
- Netty入门(三)之web服务器
Netty入门(三)之web服务器 阅读前请参考 Netty入门(一)之webSocket聊天室 Netty入门(二)之PC聊天室 有了前两篇的使用基础,学习本文也很简单!只需要在前两文的基础上稍微改 ...
- Netty入门(1) - 简介
什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Tomcat和Netty有什么区别? Netty和Tom ...
- Netty入门教程——认识Netty
什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Netty 是一个广泛使用的 Java 网络编程框架(N ...
- Netty入门与实战教程总结分享
前言:都说Netty是Java程序员必须要掌握的一项技能,带着不止要知其然还要知其所以然的目的,在慕课上找了一个学习Netty源码的教程,看了几章后着实有点懵逼.虽然用过Netty,并且在自己的个人网 ...
- Netty(六)UDP在netty中的使用
关于UDP的介绍,这里不在阐述.相比于TCP而言,UDP不存在客户端和服务端的实际链接,因此不需要为连接(ChannelPipeline)设置handler. 服务端: public void run ...
- Netty入门之客户端与服务端通信(二)
Netty入门之客户端与服务端通信(二) 一.简介 在上一篇博文中笔者写了关于Netty入门级的Hello World程序.书接上回,本博文是关于客户端与服务端的通信,感觉也没什么好说的了,直接上代码 ...
- 脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?
本文引用了“帅地”发表于公众号苦逼的码农的技术分享. 1.引言 搞网络通信应用开发的程序员,可能会经常听到外网IP(即互联网IP地址)和内网IP(即局域网IP地址),但他们的区别是什么?又有什么关系呢 ...
- netty入门(一)
1. netty入门(一) 1.1. 传统socket编程 在任何时候都可能有大量的线程处于休眠状态,只是等待输入或者输出数据就绪,这可能算是一种资源浪费. 需要为每个线程的调用栈都分配内存,其默认值 ...
随机推荐
- js 前端分页空间控件
现在web注重用户体验与交互性,ajax 提交数据的方式很早就流行了,它能够在不刷新网页的情况下局部刷新数据.前端分页多是用ajax请求数据(其他方式也有比如手动构造表单模拟提交事件等).通过js将查 ...
- centos7配置java环境
首先自行下载jdk的tar.gz的包,上传至相应服务器目录下,比如我的是:/usr/java下,然后解压缩,之后进行如下操作: 注意要修改/etc/profile文件,在末尾添加内容: export ...
- Java基础教程(23)--lambda表达式
一.初识lambda表达式 1.定义 lambda表达式是一个可传递的代码块,或者更确切地说,可以把lambda表达式理解为简洁地表示可传递的匿名方法的一种方式.它没有名称,但它有参数列表.函数主 ...
- Win10 新功能 改变显示器色彩
如果你是一个爱看书的工作族,相信一定梦想你的电脑变得跟Kindle一样,这样每天盯着电脑几个小时,眼睛都不会痛了……下面就来看看Win10带来的新体验吧! Ctr+ Windows Key + C 可 ...
- 面试中常问的List去重问题,你都答对了吗?
面试中经常被问到的list如何去重,用来考察你对list数据结构,以及相关方法的掌握,体现你的java基础学的是否牢固. 我们大家都知道,set集合的特点就是没有重复的元素.如果集合中的数据类型是基本 ...
- 理解Java线程
使用多线程的目的是更好的利用cpu资源,大部分多线程代码都可以用单线程来实现,但也有无法用单线程实现的,如:生产者消费者模型 下面对一些常用的概念进行区分: 多线程:指的是这个程序(一个进程)运行时产 ...
- nginx配置https转发到tomcat(使用自签名的证书)
一.使用openSSL生成自签名的证书 1.生成RSA私钥 命令:openssl genrsa -des3 -out server.key 1024 说明:生成rsa私钥,des3算法,1024强度, ...
- POJ3186(KB12-O DP)
Treats for the Cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5801 Accepted: 30 ...
- grafana启用mysql作为的后台数据库
vim grafana-5.4.2/conf/defaults.ini grafana默认使用sqlite3使用后台数据库,可选用mysql,postgres,sqlite3. 重新启动 注意: gr ...
- 纯小白入手 vue3.0 CLI - 2.6 - 组件的复用
vue3.0 CLI 真小白一步一步入手全教程系列:https://www.cnblogs.com/ndos/category/1295752.html 我的 github 地址 - vue3.0St ...