TCP粘包、拆包与通讯协议详解
将动静区分为动静头和动静体,在动静头中,我们行使一个整形数字,譬喻一个int,来暗示动静体的长度。而动静体现实现实要发送的二进制数据字节。以下是一个根基名目:
在变长协议中:
提醒:Netty中提供了LengthFieldPrepender给现实内容Content举办编码添加Length字段,接管方行使LengthFieldBasedFrameDecoder解码。 3.4 序列化 序列化本质上已经不是为了办理粘包和拆包题目,而是为了在收集开拓中可以越发的便捷。在变长协议中,我们看到可以在现实要发送的数据之前加上一个length字段,暗示现实要发送的数据的长度。这现实上给我们了一个很好的思绪,我们完全可以将一个工具转换成二进制字节,来举办通讯,譬喻行使一个Request工具暗示哀求,行使一个Response工具暗示相应。 序列化框架有许多种,我们在选择时,首要思量序列化/反序列化的速率,序列化占用的体积,多说话支持等。下面列出了业界风行的序列化框架: 提醒:xml、json也属于序列化框架的领域,上面的表格中并没有列出。 一些收集通讯的RPC框架凡是会支持多种序列化方法,譬喻dubbo支持hessian、json、kyro、fst等。在支持多种序列化框架的环境下,在协议中凡是必要有一个字段来暗示序列化的范例,譬喻,我们可以将上述变长协议的名目改革为:
这里行使1个字节暗示Serializer的值,行使差异的值代表差异的框架。 发送方,选择好序列化框架后编码后,必要指定Serializer字段的值。 吸取方,在解码时,按照Serializer的值选择对应的框架举办反序列化; 3.5 压缩 凡是,为了节减收集开销,在收集通讯时,可以思量对数据举办压缩。常见的压缩算法有lz4、snappy、gzip等。在选择压缩算法时,我们首要思量压缩比以及解压缩的服从。 我们可以在收集通讯协议中,添加一个compress字段,暗示回收的压缩算法:
凡是,我们没有须要行使一个字节,来暗示回收的压缩算法,1个字节可以标识256种也许环境,而常用压缩算法也就那么几种,因此凡是只必要行使2~3个bit来暗示回收的压缩算法即可。 其它,因为数据量较量小的时辰,压缩比并不会太高,没有须要对全部发送的数据都举办压缩,只有再高出必然巨细的环境下,才思量举办压缩。如rocketmq,producer在发送动静时,默认动静巨细高出4k,才会举办压缩。因此,compress字段,应该有一个值,暗示没有行使任何压缩算法,譬喻行使0。 3.6 查错校验码 一些通讯协议传输的数据中,还包括了查错校验码。典范的算法如CRC32、Adler32等。java对这两种校验方法都提供了支持,java.util.zip.Adler32、java.util.zip.CRC32。
这里并差池CRC32、Adler32举办具体声名,首要是思量,为什么必要举办校验? 有人说是由于思量到安详,这个来由好像并不充实,由于我们已经有了TLS层的加密,CRC32、Adler32的浸染不该该是为了思量安详。 一位同事的概念,我很是拥护:二进制数据在传输的进程中,也许由于电磁滋扰,导致一个高电平酿成低电平,可能低电平酿成高电平。这种环境下,数据相等于受到了污染,此时通过CRC32等校验值,则可以验证数据的正确性。 其它,凡是校验机制在通讯协议中,是可选的设置的,并不必要逼迫开启,其固然可以担保数据的正确,可是计较校验值也会带来一些特另外机能丧失。如Mysql主从同步,固然高版本默认开启CRC32校验,可是也可以通过设置禁用。 3.7 小结 本节通过一些根基的案例,讲授了在TCP编程中,怎样通过协议来办理粘包、拆包题目。在现实开拓中,凡是我们的协议会越发伟大。譬喻,一些RPC框架,会在协议中添加独一标识一个哀求的ID,一些支持双向通讯的RPC框架,如sofa-bolt,还会添加一个偏向信息等。虽然,所谓伟大,无非是在协议中添加了某个字段用于某个用途,只要弄清晰这些字段的寄义,也就不伟大了。
(编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |