Netty——高级内置解码器、编码器、ByteBuf
netty通讯需要对数据进行编码,解码,于是我们需要用到netty的编码器、解码器
netty 提供的解码器
DelimiterBasedFrameDecoder 解决TCP的粘包解码器
StringDecoder 消息转成String解码器
LineBasedFrameDecoder 自动完成标识符分隔解码器
FixedLengthFrameDecoder 固定长度解码器,二进制
Base64Decoder base64 解码器
netty 提供的编码器
Base64Encoder base64编码器
StringEncoder 消息转成String编码器
LineBasedFrameDecoder 自动完成标识符分隔编码器 MessageToMessageEncoder 根据 消息对象 编码为消息对象 对于 netty的数据传递都是ByteBuf,我们一般重写以上的解码器、编码器来实现自己的逻辑
1、DelimiterBasedFrameDecoder 解决TCP的粘包解码器
IODecoder 继承
/**
* 解码
* DelimiterBasedFrameDecoder 防止 沾包
* @author flm
* 2017年10月30日
*/
public class IODecoder extends DelimiterBasedFrameDecoder { public static final AttributeKey<DeviceSession> KEY = AttributeKey.valueOf("IO"); // 保存
private static final Logger log = Logger.getLogger(IODecoder.class); // 防止 沾包 分隔符
private static ByteBuf delimiter = Unpooled.copiedBuffer("\n".getBytes()); // 沾包 分割符 \n
private static int maxFrameLength = 1024 * 6; //数据大小 public IODecoder() {
super(maxFrameLength, delimiter);
} /**
* 重新 自定义解码
*/
@Override
protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
// 对数据 buffer 解码
return super.decode(ctx, buffer);
}
}
2、MessageToMessageEncoder 编码器
/**
* 指令 编码
* MessageToMessageEncoder<PushEntity>
* 把 PushEnty 编码为string
* @author flm
* 2017年11月3日
*/
public class IOEncoder extends MessageToMessageEncoder<PushEntity> { private static final Logger LOG = Logger.getLogger(IOEncoder.class); public IOEncoder() {
super();
} /**
* 重写 编码
*/
@Override
protected void encode(ChannelHandlerContext ctx, PushEntity msg, List<Object> out) throws Exception {
try {
PushEntity push = (PushEntity) msg; } // 以字符串 形式 发送
out.add(ByteBufUtil.encodeString(ctx.alloc(), CharBuffer.wrap(msg.toString()), Charset.defaultCharset())); } catch (Exception e) { e.printStackTrace(); }
}
}
3、 FixedLengthFrameDecoder 固定长度解码器,二进制
/**
*
* 功能描述:协议消息解码器
* 把 btyeBuf 转为 RootMessage对象
*
*/
public class GT06MsgDecoder extends LengthFieldBasedFrameDecoder
{
public GT06MsgDecoder()
{
super(65540, 2, 1, 2, 0); //继承
} /*
* 重写 解码
*/
@Override
public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception
{
ByteBuf frame = (ByteBuf) super.decode(ctx, in);
// 读取 ByteBuf 是根据 位数来读取的
try
{
if (frame == null)
{
return null;
} int frameLen = frame.readableBytes(); // 起始位
byte[] header = new byte[GT06Constant.START_DELIMITER_LEN]; frame.readBytes(header); // 是否是0x79 0x79 开头的扩展包
boolean extPacket = false; if(Arrays.equals(GT06Constant.PACKET_START_EXT, header))
{
extPacket = true;
} int contentLen = MessageUtils.getContentLen(frameLen, extPacket); // 跳过包长度
frame.skipBytes(MessageUtils.getPacketSizeLen(extPacket)); // 消息内容
byte[] msgContent = new byte[contentLen]; // 消息序列号
byte[] sequence = new byte[GT06Constant.MESSAGE_SERIAL_LEN]; // crc校验码
byte[] crc = new byte[GT06Constant.CRC_ITU_LEN]; // 终止符
byte[] endDelimiter = new byte[GT06Constant.END_DELIMITER_LEN];
return new RootMessage(action, sequence, msgContent);
}
finally
{
if(frame != null)
{
frame.release();
}
}
}
其它的编码器,解码器都大同小异,不懂的可以看源码
其实解码、编码,最最重要的是对BtyeBuf的读取
BtyeBuf读操作主要提供以下功能:
- readByte:取1字节的内容;
- skipBytes: 跳过内容
- readUnsignedByte:取1字节的内容,返回(
(short) (readByte() & 0xFF));(能把负数转换为无符号吗?) - readShort:取2字节的内容,返回转换后的
short类型; - readUnsignedShort:取2字节的内容,返回
readShort() & 0xFFFF; - readMedium:取3字节的内容,返回转换后的
int类型; - readUnsignedMedium:取3字节的内容,返回转换后的
int类型; - readInt:取4字节的内容;
- readUnsignedInt:取4字节的内容,返回
readInt() & 0xFFFFFFFFL; - readLong:取8字节的内容;
- readChar:取1字节的内容;
- readFloat:取4字节的int内容,转换为
float类型; - readDouble:取8字节的long内容,转换为
double类型; - readBytes:取指定长度的内容,返回
ByteBuf类型; - readSlice:取指定长度的内容,返回
ByteBuf类型; - readBytes:取指定长度的内容到目标容器。
写操作
写操作提供的功能主要是往ByteBuf中写入byte内容,不再一一赘述。主要区别在于写入前根据类型转换为相对应长度的byte数组。
主要函数是:writeBoolean、writeByte、writeShort、writeMedium、writeInt、writeLong、writeChar、writeFloat、writeDouble、writeBytes、writeZero。
边界值安全
不论读或写,肯定会存在ByteBuf数据为空或满的情形,作为数据容器,要存在边界值检查,确保读写安全。
Netty——高级内置解码器、编码器、ByteBuf的更多相关文章
- Netty高级应用及聊天室实战
Netty 高级应用 1. 编解码器 概念:在网络应用中,需要实现某种编解码器.将原始字节数据与自定义消息数据进行相互转换.网络中都是以字节码的形式传输的. 对Netty而言,编解码器由两部分组成:编 ...
- Netty 系列三(ByteBuf).
一.概述和原理 网络数据传输的基本单位总是字节,Netty 提供了 ByteBuf 作为它的字节容器,既解决了 JDK API 的局限性,又为网络应用程序提供了更好的 API,ByteBuf 的优点: ...
- netty高级篇(3)-HTTP协议开发
一.HTTP协议简介 应用层协议http,发展至今已经是http2.0了,拥有以下特点: (1) CS模式的协议 (2) 简单 - 只需要服务URL,携带必要的请求参数或者消息体 (3) 灵活 - 任 ...
- Netty实战五之ByteBuf
网络数据的基本单位总是字节,Java NIO 提供了ByteBuffer作为它的字节容器,但是其过于复杂且繁琐. Netty的ByteBuffer替代品是ByteBuf,一个强大的实现,即解决了JDK ...
- Netty(7)源码-ByteBuf
一.ByteBuf工作原理 1. ByteBuf是ByteBuffer的升级版: jdk中常用的是ByteBuffer,从功能角度上,ByteBuffer可以完全满足需要,但是有以下缺点: ByteB ...
- Netty——高级发送和接收数据handler处理器
netty发送和接收数据handler处理器 主要是继承 SimpleChannelInboundHandler 和 ChannelInboundHandlerAdapter 一般用netty来发送和 ...
- netty: 以默认的ByteBuf作为传输数据
client部分代码: //线程 EventLoopGroup worker = new NioEventLoopGroup(); //辅助类 Bootstrap b = new Bootstrap( ...
- 【Netty技术专题】「原理分析系列」Netty强大特性之ByteBuf零拷贝技术原理分析
零拷贝Zero-Copy 我们先来看下它的定义: "Zero-copy" describes computer operations in which the CPU does n ...
- Netty 核心容器之ByteBuf 结构详解
原文链接 Netty 核心容器之ByteBuf 结构详解 代码仓库地址 Java的NIO模块提供了ByteBuffer作为其字节存储容器,但是这个类的使用过于复杂,因此Netty实现了ByteBuf来 ...
随机推荐
- redis之hello
1.创建一个maven工程 2.进入redis官网 https://github.com/xetorthio/jedis 3.找到 <!--导入到pom.xml文件中--><depe ...
- Gitlab 赋予某台机器git clone的权限 Deploy key
开发项目CI(持续化部署)的时候,需要赋予jeckins所在的机器从gitlab远程仓库克隆代码到本地的权限. 之前我们基本都是通过管理gitlab某个项目的成员的方式,管理gitlab的权限. 但是 ...
- 使用命令行打包 nuget 包
对于那些不打算涉及这么复杂而又想制作自己的 nuget 包的园友们,我是推荐使用 Nuget Package Explorer 来制作的.关于这个图形化的 nuget 包管理软件的使用,博客园内有相关 ...
- 经过实际验证的C#调用Haskell的方法
[系统环境] Windows Server 2008 R2,Haskell Platform 2013.2.0.0,ghc 7.6.3,cabal 1.16.0 [操作步骤] 1. 安装Windows ...
- Python进程池举例
multiprocessing包 from multiprocessing import Pool def a(num): print num if __name__ == "__main_ ...
- C#爬取京东手机数据+PowerBI数据可视化展示
此系列博文链接 C#爬虫基本知识 Html Agility Pack解析html TODO: EF6中基本认识. EF6操作mysql MySQL乱码问题 C#爬虫 在开头贴一下github仓库地址, ...
- 20164317 《网络对抗技术》Exp6 信息搜集与漏洞扫描
Exp6 信息搜集与漏洞扫描 一.原理与实践说明 (1)实践原理 信息搜集:渗透测试中首先要做的重要事项之一,搜集关于目标机器的一切信息 间接收集 DNS记录扫描和枚举 CorpWatch:auxil ...
- Python中super()的用法
参考链接:https://www.cnblogs.com/shengulong/p/7892266.html super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是 ...
- Git-工作区和暂存区的概念
工作区(Working Directory):就是在电脑里能看到的目录,如testcase文件夹就是一个工作区. 版本库(Repository):工作区有一个隐藏目录.git,是Git的版本库. ...
- svn重新安装后报You need to upgrade the working copy first错误
问题来源 最近重新安装了操作系统,安装了一个最新版的svn,提交代码的时候报了一个错误:You need to upgrade the working copy first,!网上找了很多解决办法,都 ...