目录:

  1. 粘包 & 拆包及解决方案 ByteToMessageDecoder
  2. 基于长度编解码器
  3. 基于分割符的编解码器
  4. google 的 Protobuf 序列化介绍
  5. 其他的

 前言

Netty 作为一个网络框架,对 TCP 连接中的问题都做了全面的考虑,比如粘包拆包导致的半包问题,如何编解码,如何实现私有协议,序列化等等。本文主要针对这些问题做一个简单介绍,目的是想对整个 Netty 的编解码框架做一个全盘的审视,以确保在后面的源码学习中不会一叶障目不见泰山。

1. 粘包 & 拆包及解决方案 ByteToMessageDecoder

由于TCP是面向字节流的,什么意思呢:虽然应用程序和 TCP 的交互是一次一个数据块(大小不等),但 TCP 把应用程序交下来的数据仅仅看成式一连串的无结构的字节流。TCP 并不知道所传送的字节流的含义。

因此 TCP 不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系(例如,发送方应用程序交给发送方的 TCP 共 10 个数据块,但接收方的 TCP 可能只用了 4 个就把收到的字节流交付上层的应用程序)。

同时,TCP 不关心应用进程一次把多长的报文发送到 TCP 的 缓存 中,而是根据对方给出的窗口值和当前网络阻塞的程度来决定一个报文段应包含多少个字节(UDP 发送的报文长度是应用进程给出的)。如果应用进程传送到 TCP 缓存的数据块太长,TCP 就可以把他划分短一点再传送。如果应用程序一次只发来一个字节,TCP 也可以等待积累有足够多的字节后再构成报文段发送出去。

  • TCP 发送报文一般是 3 个时机:
  1. 缓冲区数据达到 最大报文长度 MSS
  2. 由发送端的应用进程指明要求发送报文段,即 TCP 支持的推送(push)操作;
  3. 当发送方的一个计时器期限到了,即使长度不超过 MSS ,也发送。

以上引自《计算机网络-----谢希仁》。

说了这么多,TCP 的这种机制,会导致什么问题呢?粘包问题。有了粘包,就需要拆包。

  • 一般解决粘包拆包问题有 4 种办法:
  1. 固定数据的长度,比如 100 字节,如果不够就补空格。
  2. 学习 HTTP ,FTP 等,使用回车换行符号。
  3. 将消息分为 head 和 body,head 中包含 body 长度的字段,一般 head 的第一个字段使用 int 值来表示 body 长度。
  4. 使用更复杂的应用层协议(等于没说 =_= !)。

Netty 作为一个网络框架,直接和 TCP 打交道,自然考虑了这个问题。而解决这个问题的主要实现就是抽象类 ByteToMessageDecoder,详见 Netty 解码器抽象父类 ByteToMessageDecoder 源码解析。Netty 使用了模板设计模式,这个类只定义了共有行为,具体解码实现还是子类,比如上面提到的 4 种方式。

2. 基于长度编解码器的具体实现

基于长度的实现有2个现成的类:

  1. FixedLengthFrameDecoder 基于构造函数中的固定长度
    该类很简单,构造方法中,传入一个整数,该解码器就会按照这个数字对累积区的字节进行切分。

  2. LengthFieldBasedFrameDecoder 基于流中动态的长度
    该类比较复杂。构造函数参数多达 6 个,在构建私有协议栈时大有用处。

3. 基于分割符的编解码器

同样有 2 个:

  1. DelimiterBasedFrameDecoder 用户提供分割符。
    该类比较简单,根据用户提供的分割符对累积区的内容进行分割。性能相对不是那么完美。

  2. LineBasedFrameDecoder 基于换行符,支持多种换行符 \n \r\n 速度相比自定义较快。
    该类使用更简单,根据换行符进行拆包粘包。

4. google 的 ProtobufDecoder ProtobufEncoder 序列化介绍

Netty 中有很多序列化工具,比如 Jboss 的 Marshalling,同时也支持 Java 标准的序列化。 但我们重点关注 google 的 protobuf 库。因为它的性能最高。

上面的 4 个解码器都是基于 ByteToMessageDecoder,将粘包的字节转为用户需要的字节。而ProtobufDecoder 不是继承自 ByteToMessageDecoder,而是继承自 MessageToMessageDecoder,名字都不同。MessageToMessageDecoder 的作用是什么呢?

从名字上看,该类用于将两个消息进行转换(比如一种 POJO 转成另一种)。后面我们将花大篇幅讲述这个类库。

5. 其他的

1. TooLongFrameException

由于 Netty 是一个异步框架,所以需要在字节可以解码之前在内存中缓冲他们。因此不能让解码器缓冲大量的数据以至于耗尽可用的内存。为了解决这个问题,Netty 提供了 TooLongFrameException 类,其将由解码器在帧超出指定的大小限制时抛出异常。

你可以设置一个最大的阈值,当超过该阈值,这抛出异常。

2. 写大型数据的 FileRegion

有时候你可能需要写一个大型的数据,如果不停的写入,可能导致 OOM,所以在写大型数据时,需要准备好处理到远程节点的连接时慢速连接的情况,这种情况会导致内存释放的延迟。

我们可以使用 NIO 的零拷贝特性,这种特性消除了将文件内容从文件系统移动到网络栈的复制过程。而我们所需要做的就是使用一个 FileRegion 接口的实现。
官方定义:

通过支持零拷贝的文件传输的 Channel 来发送的文件区域。

6. 总结

本文并没有刨析源码,主要是针对 Netty 中现有的或者设计的编解码,序列化等工具做一个介绍,方便后面有条不紊的按照这个路线研究他们的具体实现。

good luck!!!!

转载于:https://www.cnblogs.com/stateis0/p/9062162.html

Netty 粘包 拆包 编码 解码 序列化 介绍相关推荐

  1. Netty粘包拆包、自定义Protostuff编解码器

    1.Netty粘包拆包 TCP是一个"流"协议,所谓流,就是没有界限的一长串二进制数据.TCP作为传输层协议并不了解上层业务数据的具体含义,会根据TCP缓冲区的实际情况进行数据包的 ...

  2. Netty粘包拆包问题说明、演示拆包粘包情况代码以及解决

    概述 TCP传输协议是面向连接的,面向流提供高可靠的服务.收发两端(服务端和客户端)都要有一一成对的socket,因此,发送端为了将多个发给接收端的包,更有效地发给对方,使用了优化算法(Nagle算法 ...

  3. netty粘包拆包之LengthFieldBasedFrameDecoder解码器

    ​目录           一. 背景简介           二. 应用           三.源码 一.背景简介 LengthFieldBasedFrameDecoder 基于长度字段解码器,是 ...

  4. netty的编解码、粘包拆包问题、心跳检测机制原理

    文章目录 1. 编码解码器 2. 编解码序列化机制的性能优化 3. Netty粘包拆包 4. Netty心跳检测机制 5. Netty断线自动重连实现 1. 编码解码器 当你通过netty发送或者接受 ...

  5. 深入理解Netty编解码、粘包拆包、心跳机制

    点赞再看,养成习惯,公众号搜一搜[一角钱技术]关注更多原创技术文章. 本文 GitHub org_hejianhui/JavaStudy 已收录,有我的系列文章. 前言 BIO .NIO .AIO 总 ...

  6. Netty编解码,粘包拆包及零拷贝

    Netty编解码 Netty涉及到编解码的组件有Channel.ChannelHandler.ChannelPipe等,先大概了解下这几个组件的作用. ChannelHandler ChannelHa ...

  7. 什么是粘包和拆包,Netty如何解决粘包拆包?

    Netty粘包拆包 TCP 粘包拆包是指发送方发送的若干包数据到接收方接收时粘成一包或某个数据包被拆开接收. 如下图所示,client 发送了两个数据包 D1 和 D2,但是 server 端可能会收 ...

  8. http协议解决粘包拆包半包 的编码解码过程、 以及netty 使用http协议的原理

    本文主要介绍netty对http协议解析原理,着重讲解keep-alive,gzip,truncked等机制,详细描述了netty如何实现对http解析的高性能. 1 http协议 1.1 描述 标示 ...

  9. Netty介绍与实战(三)之粘包拆包

    一.传统NIO架构 step1. 我们传统的nio架构已经解决了多路复用,零拷贝等问题,已经十分优秀了,那为什么我们现在Netty如此火热呢? 1) 首先他使用简单,基本上都是模板化,我们可以更专注业 ...

最新文章

  1. Cmake的install与file命令的区别
  2. 30K程序员的简述:如何成为高级开发人员
  3. Matlab中特征选择reliefF算法使用方法(分类与回归)
  4. asp教室使用_为什么要在教室中使用开放式硬件?
  5. 【java】分布式一致性hash算法
  6. WSL2 即将普遍可用,Linux 内核提供方式改变
  7. Error:express-session deprecated undefined resave option; provide resave option app.js:17:10
  8. isbool php,PHP PHPUnit assertIsBool()用法及代码示例
  9. 广数25i系统倒刀回刀m代码_广数系统指令
  10. WINRAR 4.00版注册方法
  11. java十进制_JAVA 十进制 转换成 三进制
  12. 二十九-使用RealSenseD435进行ORBSLAM2实时三维重建
  13. 办流量卡要身份证照片,办流量卡是否需要身份证正反面照片
  14. 交叉编译xorg-server
  15. Blender 插件开发 将object设置成bpy.context.object
  16. 支持数位板的远程软件,实现远程使用 Wacom 数位板
  17. sap 用户权限表_sap权限相关后台表
  18. 有关QJ_Filecenter在vue中的使用和组件封装
  19. 数学优化入门:凸优化
  20. 分享Delphi处理EXCEL源码

热门文章

  1. 跨平台PHP调试器设计及使用方法——拾遗
  2. FFmpeg在Windows上通过dshow编解码方式设置为mjpeg并实时显示测试代码
  3. 程序员的自我修养--链接、装载与库笔记:系统调用与API
  4. FFmpeg中拉取rtsp视频流并缩放显示测试代码
  5. 大学生如何合理使用计算机,大学生计算机合理使用引导分析
  6. js室内地图开发_如何使用JS来开发室内三维地图的轨迹回放功能
  7. java ftp 判断文件是否存在_FTP判断文件是否存在
  8. c# 读hex_c#十六进制到位转换(c# hex to bit conversion)
  9. uni-app h5页面左上角出现“取消“字眼解决办法
  10. 12-flutter Textfield的使用