资讯专栏INFORMATION COLUMN

分隔符和定长解码器的应用

lemon / 911人阅读

摘要:以流的方式进行数据传输上层的应用协议为了对消息进行区分往往采用如下中方式消息长度固定累计读取到长度总和为定长的报文后就认为读到了一个完整的消息将计数器置位重新开始读取下一个数据报将回车换行符作为消息结束符例如协议这种方式在文本协议中应用比较

TCP 以流的方式进行数据传输, 上层的应用协议为了对消息进行区分, 往往采用如下 4 中方式.

消息长度固定, 累计读取到长度总和为定长 LEN 的报文后, 就认为读到了一个完整的消息; 将计数器置位, 重新开始读取下一个数据报;

将回车换行符作为消息结束符, 例如 FTP 协议, 这种方式在文本协议中应用比较广泛.

将特殊的分隔符最为消息的结束标志, 回车换行符就是一种特殊的结束分隔符;

通过在消息头中定义长度字段来标识消息的总长度.

Netty 对上面 4 种应用做了统一的抽象, 提供了 4 种解码器来解决对应用的问题.

之前我写了 LineBasedFrameDecoder 解码器的使用, 今天开始学习如何使用 DelimiterBasedFrameDecoderFixedLengthFrameDecoder.

DelimiterBasedFrameDecoder 应用开发

通过对 DelimiterBasedFrameDecoder 的使用, 我们可以自动完成以分隔符作为码流结束标识的消息的解码.

还是修改 initChannel 方法

ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new TimeServerHandler());

我们使用 $_ 作为分隔符, 创建 DelimiterBasedFrameDecoder 对象, 将其加入到 ChannelPipeline 中. DelimiterBasedFrameDecoder 有多个构造方法, 这里我们传递两个参数: 第一个 1024 表示单条消息的最大长度, 当达到该长度后仍然没有检查到分隔符, 将抛出 TooLongFrameException 异常, 防止由于异常码流缺失分隔符导致的内存溢出, 这是 Netty 解码器的可靠性保护; 第二个参数就是分隔符缓冲对象.

由于我们设置 DelimiterBasedFrameDecoder 过滤掉了分隔符, 所以返回给客户端时需要在请求消息尾部拼接分隔符 $_.
FixedLengthFrameDecoder 应用开发

FixedLengthFrameDecoder 是固定长度解码器, 它能够按照指定的长度对消息进行自动解码.

ch.pipeline().addLast(new FixedLengthFrameDecoder(10));
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new TimeServerHandler());

利用 FixedLengthFrameDecoder 解码器, 无论一次接收到多少数据报, 他都会按照构造函数中设置的固定长度进行解码, 如果是半包消息, FixedLengthFrameDecoder 会缓存半包消息并等待下个包到达后进行拼包, 直到读取到一个完整的包.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72767.html

相关文章

  • 基于定长消息java nio半包粘包处理

    摘要:接收方只需要等待,直到读到确定数量的字节,然后处理即可。而这个字节流的前个字节用于表示对象的长度,接下来的字节就是传输的对象的字节流,最后不够最大长度的用任意字节进行填充即可。 什么是tcp半包粘包?简单来讲就是接收到的tcp包并不一定是一个完整的包。它可能是1个包的一部分,也可能是多个完整包加上1个包的一部分。为什么?因为tcp的定义是面向字节流的传输协议,所以操作系统实现这个协议的...

    Loong_T 评论0 收藏0
  • netty

    摘要:设置每个数据包的大小如个字节,如果某个数据包不足个字节可能会出现丢包的情况,即该数据包未从一个端到另一个端,此时需要用空格或者既定的符号补充在数据包之间使用一些字符进行分割如号之类的,解析的时候先处理掉分隔符再拿到各个数据包就好了。 netty 概念: Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠...

    cfanr 评论0 收藏0
  • 编码解码UNICODE

    摘要:其他编码的可以参考,,的选择不考虑随机访问,,查找第个字符时间复杂度随机访问,只用之内的字符,,时间复杂度随机访问,超过了,详解编码 1.字符集vs字符编码,编码&解码 Character----->code point----->bytes 前两者字符集的关系,可以统称为codepoint;从codepoint到在计算机上的存储形式,称为编码,反过来称为解码; 字符集:单个符号(ch...

    baukh789 评论0 收藏0
  • Netty(三) 什么是 TCP 拆、粘包?如何解决?

    摘要:是一个面向字节流的协议,它是性质是流式的,所以它并没有分段。可基于分隔符解决。编解码的主要目的就是为了可以编码成字节流用于在网络中传输持久化存储。 showImg(https://segmentfault.com/img/remote/1460000015895049); 前言 记得前段时间我们生产上的一个网关出现了故障。 这个网关逻辑非常简单,就是接收客户端的请求然后解析报文最后发送...

    YanceyOfficial 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<