当前位置: 首页 > 编程日记 > 正文

Netty 粘包 拆包 编码 解码 序列化 介绍

1240

目录:

  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

相关文章:

matlab 全局变量

转自:http://matlab.net.cn/matlabjichu/2010/201005/265.html 如果你要多于一个函数共用一个简单的变量,简单的处理方法就是把这个变量在所有函数中定义为global全局变量。在命令行做同样的事情,如果你要工作空间访问上述变量。这个全局变量…

java 解决Html table的rowspan问题(osc处女作)

2019独角兽企业重金招聘Python工程师标准>>> 假如有如下html代码需要解析 <table border"1"><tr><td rowspan"3">1</td><td>1</td><td>1</td><td>1</td></tr><tr>&l…

基于C++的OpenCV常用函数

C版本的好处&#xff1a; 1、在于可以尽量避免使用指针这种危险的东西&#xff1b; 2、不用费心去release资源了&#xff0c;因为在其destructor里面&#xff0c;系统会自动帮你搞定。 3、在某些情况下会比C版本运行速度快。 在文件中包含 using namespace cv; 1. i…

基于GAN的图像水印去除器,效果堪比PS高手

作者 | 李翔转载自视说AI&#xff08;ID:techtalkai&#xff09;简介&#xff1a;李翔&#xff0c;国内某互联网大厂AI民工&#xff0c;前携程酒店图像技术负责人&#xff0c;计算机视觉和深度学习重度爱好者&#xff0c;在ICCV和CVPR等会议上发表论文十余篇。写在前面当前互联…

Flink最锋利的武器:Flink SQL入门和实战 | 附完整实现代码

作者 | 机智的王知无转载自大数据技术与架构&#xff08;ID: import_bigdata&#xff09;一、Flink SQL 背景Flink SQL 是 Flink 实时计算为简化计算模型&#xff0c;降低用户使用实时计算门槛而设计的一套符合标准 SQL 语义的开发语言。自 2015 年开始&#xff0c;阿里巴巴开始…

SQL SERVER中ROLLUP的用法

cube操作符 要使用cube&#xff0c;首先要了解group by 其实cube和rollup区别不太大&#xff0c;只是在基于group by 子句创建和汇总分组的可能的组合上有一定差别&#xff0c; cube将返回的更多的可能组合。如果在 group by 子句中有n个列或者是有n个表达式的话&#xff0c; s…

Mybait缓存机制

MyBatis同大多数ORM框架一样&#xff0c;提供了一级缓存和二级缓存的支持。 一级缓存&#xff1a;其作用域为session范围内&#xff0c;当session执行flush或close方法后&#xff0c;一级缓存会被清空。 二级缓存&#xff1a;二级缓存和一级缓存机制相同&#xff0c;但是可以自…

vs2008常用操作汇总

1、OpenCV2.1环境配置&#xff1a; (1)、Tools-->Options-->Projects and Solutions-->VCDrectories&#xff1a; Show directories for选择include files&#xff0c;加入目录 D:/Program Files/OpenCV2.1/include/opencv &#xff1b;Show directories for选择libra…

深度学习已至“瓶颈”?英特尔:数据处理是一剂良药

【导读】霍金弟子Alan Yuille在前不久发表言论称&#xff0c;至少在计算机视觉领域&#xff0c;深度学习的瓶颈已至。然而&#xff0c;人工智能与大数据的发展相辅相成&#xff0c;数据将会推动人工智能的发展&#xff0c;促进更多技术应用落地&#xff0c;将人工智能带入一个新…

WIN32 C++ 遍历文件夹

转自&#xff1a;http://blog.csdn.net/lizhigang770/archive/2010/11/30/6045242.aspx 一、先介绍一个结构 WIN32_FIND_DATA typedef struct _WIN32_FIND_DATA { DWORD dwFileAttributes; // 文件属性 FILETIME ftCreationTime; // 文件创建时间 FILETIME ft…

UIView淡入淡出动画

小小原创&#xff0c;转载请注明出处&#xff1a;http://iphone.xiaoxiaostudio.net 如果你觉得为某个UIView 加载一个全新的View在这个UIView上面时&#xff0c;想要隐藏时setHidden显得太突兀了&#xff0c;我们可以给它增加一些动画&#xff0c;iOS上默认提供了一些动画&…

sass的继承,混合宏,占位符的用法总结

SCSS中混合宏使用 mixin mt($var){ margin-top: $var; }.block { include mt(5px);span { display:block; include mt(5px); } }extend如何工作 .icon {transition: background-color ease .2s;margin: 0 .5em;}.error-icon {extend .icon;/*错误图标指定的样式... */}.info-i…

js中cookie的使用详细分析

2019独角兽企业重金招聘Python工程师标准>>> JavaScript中的另一个机制&#xff1a;cookie&#xff0c;则可以达到真正全局变量的要求。 cookie是浏览器 提供的一种机制&#xff0c;它将document 对象的cookie属性提供给JavaScript。可以由JavaScript对其进行控制&a…

从事JAVA 20年最终却败给了Python,哭了!

之前遇到一个老师&#xff0c;他从事Java行业20年了&#xff0c;在Python兴起的时候&#xff0c;他周围的其他同行们都在纷纷学习Python方面的知识&#xff0c;连他的学生也问他“老师&#xff0c;你为什么不学Python呢&#xff1f;”。当这位听到学生这个问题的时候&#xff0…

c++删除文件夹

转自&#xff1a;http://blog.csdn.net/sshhbb/archive/2010/12/07/6061029.aspx c语言本身是不能删除文件或文件夹的&#xff0c;他们是windows操作系统里的东西&#xff0c;所以得借助其api函数。 其一&#xff1a;使用shell 接口&#xff1a; void FileDelete(CString di…

解决bootstrap下的图片自适应问题

.img-responsive {display: block; height: auto; max-width: 100%; }转载于:https://www.cnblogs.com/qjuly/p/9809910.html

边缘检测、Hough变换、轮廓提取、种子填充、轮廓跟踪

转自&#xff1a;http://blog.sina.com.cn/s/blog_6c083cdd0100nm4s.html 7.1 边沿检测 我们给出一个模板 和一幅图象 。不难发现原图中左边暗&#xff0c;右边亮&#xff0c;中间存在着一条明显的边界。进行模板操作后的结果如下&#xff1a; 。 可以看出&#xff0c;第3…

JS Array 中 shift 和 pop 的妙用

在 JS Array 中支持两个方法&#xff0c;shift() 和 pop()&#xff0c;分别是指从一个数据中的最前面和最后面删除一个值&#xff0c;并返删除值。看一个示例就明白了&#xff1a; var arr [s,o,f,i,s,h]; arr.shift(); // 返回 s arr; // 目前是 [o,f,i,s,h…

当今主流分割网络有哪些?12篇文章一次带你看完

作者 | 孙叔桥来源 | 转载自有三AI&#xff08;ID: yanyousan_ai&#xff09;本文的12篇文章总结了当前主流的分割网络及其结构&#xff0c;涵盖从编解码结构到解码器设计&#xff1b;从感受野到多尺度融合&#xff1b;从CNN到RNN与CRF&#xff1b;从2D分割到3D分割&#xff1b…

正确生成浮点型的方法,解决sqlachemy Float浮点型的坑,生成float类型时,长度和精度均为0,导致查询不到结果!...

问题描述 在使用flask_sqlachemy时&#xff0c;给price字段选择了Float类型&#xff0c;数据库用的mysql&#xff0c;生成数据库表后&#xff0c;发现 from sqlalchemy import Float,Column price Column(Float,default0.00) 虽然能存储float类型&#xff0c;结果如下 但是查询…

图像轮廓的提取和绘制

转自&#xff1a;http://blog.csdn.net/gnuhpc/archive/2009/06/18/4278105.aspx <>var ultimaFecha ; <>document.write(ultimaFecha); #include "highgui.h" #include "cv.h" #include <iostream> #include <iomanip> using …

上海交大张拳石:神经网络的可解释性,从经验主义到数学建模

作者 | 张拳石来源 | 转载自知乎Qs.Zhang张拳石本来想把题目取为“从炼丹到化学”&#xff0c;但是这样的题目太言过其实&#xff0c;远不是近期可以做到的&#xff0c;学术研究需要严谨。但是&#xff0c;寻找适当的数学工具去建模深度神经网络表达能力和训练能力&#xff0c;…

计算机网络模型到底是七层?五层?四层?

1.Introduction 本篇文章的初衷是在做Android网络开发时经常接触各种协议&#xff0c;比如HTTP、XMPP、HLS、RTSP、TCP等协议&#xff0c;对网络的模型和层次有个直观的了解可以做到心中有数。OSI参考模型是七层&#xff0c;TCP/IP模型是四层&#xff0c;计算机网络&#xff08…

【推荐】使用Ultrapico Expresso学习正则表达式

推荐理由Ultrapico Expresso是我工作中经常使用的一个非常强大的正则表达式构建、测试以及代码生成工具。它能够对你构建的正则表达式进行解析、验证&#xff0c;并输出解析结果&#xff0c;提供性能测试工具&#xff0c;支持C#、VB等代码生成&#xff0c;最重要的是&#xff0…

OpenCV中常用到的轮廓处理函数汇总

转自&#xff1a;http://fsa.ia.ac.cn/opencv-doc-cn/opencv-doc-cn-0.9.7/ref/opencvref_cv.cn.htm ApproxChains 用多边形曲线逼近 Freeman 链 CvSeq* cvApproxChains( CvSeq* src_seq, CvMemStorage* storage,int methodCV_CHAIN_APPROX_SIMPLE,double parameter0, int mi…

《Linux内核原理与分析》第二周作业

反汇编一个简单的C程序 1、实验要求 使用&#xff1a; gcc –S –o test.s test.c -m32 命令编译成汇编代码&#xff0c;对汇编代码进行分析总结。其中test.c的具体内容如下&#xff1a; int g(int x) {return x 3; }int f(int x) {return g(x); }int main(void) {return f(8)…

首次!腾讯全面公开整体开源路线图

6月25日&#xff0c;由Cloud Native Computing Foundation (CNCF) 主办的云原生技术大会在上海举办&#xff0c;腾讯开源联盟主席、腾讯开源管理办公室委员、Apache Member堵俊平首次公开了腾讯整体的开源战略路线图。 堵俊平表示&#xff1a;“腾讯开源提倡‘开放、共享、合力…

201771010111李瑞红《面向对象的程序设计》第八周实验总结

实验八接口的定义与使用 实验时间 2018-10 理论部分 6.1 接口:用interface声明&#xff0c;是抽象方法和常量值定义的集 合。从本质上讲&#xff0c;接口是一种特殊的抽象类。 在Java程序设计语言中&#xff0c;接口不是类&#xff0c;而是对类 的一组需求描述&#xff0c;由常…

崛起的Python,真的影响了76万人?

随着AI的兴起&#xff0c;Python彻底火了。据Stack Overflow调研报告&#xff1a;Python的月活用户已超越了Java、成为第一&#xff0c;全民Python已为“大势所趋”。那么&#xff0c;程序员有必要学Python吗&#xff1f;如何高效掌握Python&#xff1f;程序员为啥要学Python&a…

OpenCV查找轮廓

转自&#xff1a;http://westice.javaeye.com/blog/721225 主要函数是 cvFindContours(tour_buf,storage,&contour,sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); tour_buf 是需要查找轮廓…