Netty拆包粘包以及编解码技术

TCP拆包粘包

TCP是个流协议,所谓流就是没有界限的一串数据。TCP底层并不了解上层业务数据的具体定义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。

这里写图片描述
TCP粘包拆包发生的原因:
问题产生的原因有三个,分别如下:

  • 应用程序Write写入的字节大小大于套接口发送缓冲区的大小。
  • 进行MSS大小的TCP分段。
  • 以太网帧的payload大于MTU进行IP分片。

这里写图片描述
粘包问题的解决策略:
由于底层的TCP无法理解上层的业务数据,所以底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层的应用协议栈设计来解决:

① 消息定长,例如每个报文的大小为固定长度200字节,如果不够空位补空格。 ② 在包尾增加回车换行符进行分割,例如FTP协议。
③ 将消息分为消息头和消息体,消息头中包含表示消息总长度(或者消息体总体长度) 的字段,通常涉及思路为消息头的第一个字段使用init32来表示消息的总长度。
④ 更复杂的应用层协议。

LineBasedFrameDecoder和StringDecoder的原理分析:

LineBasedFrameDecoder的工作原理是它依次便利ByteBuf中的可读字节,判断看是否有“\n”或者“\r\n”,如果有就以此位置为结束位置,从可读索引到结束位置区间的字节就组成了一行。他是以换行符为结束标志的解码器,支持携带结束符或者不携带结束符两种解码方式,同时支持配置当行的最大长度。如果连续读取带最大长度后任然没有发现换行符,就会抛出异常,同时忽略掉之前读到的异常码流。

StringDecoder的功能非常简单,就是将接收到的对象转换成字符串,然后继续调用后面的handler。LineBasedFrameDecoder+StringDecoder组合就是按行切换的文本解码器,它被设计用来支持TCP的粘包和拆包。
DelimiterBasedFrameDecoder特殊符号解码器,其已经过滤掉了分隔符。

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

编解码技术

当进行远程跨进程服务调用时,需要把传输的java对象编码为字节数组或者ByteBuffer对象,而当远程服务读取到ByteBuffer对象或者字节数组时,需要将其解码为发送时的java对象,这被称为java编解码技术。
在远程服务调用时(RPC)时,很少直接使用java序列化进行消息的编解码和传输。
Java序列化的缺点:

① 无法跨语言:java序列化技术是java语言内部的私有协议其他语言不支持。
③ 序列化性能太低。

可以使用第三方的序列化工具实现,此处不做介绍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值