加入收藏 | 设为首页 | 会员中心 | 我要投稿 西安站长网 (https://www.029zz.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

TCP粘包、拆包与通信协议详解

发布时间:2019-10-18 15:23:53 所属栏目:教程 来源:田守枝
导读:副标题#e# 在TCP编程中,我们使用协议(protocol)来解决粘包和拆包问题。本文将详解TCP粘包和半包产生的原因,以及如何通过协议来解决粘包、拆包问题。让你知其然,知其所以然。 1 TCP粘包、拆包图解 由于TCP传输协议面向流的,没有消息保护边界。一方发送的

那么根据协议,我们可以判断出来,这里包含了3个有效的请求报文,如下:

  1. +-----+-----+-----+ 
  2.    | ABC | DEF | GHI | 
  3.    +-----+-----+-----+ 

在定长协议中:

  • 发送方,必须保证发送报文长度是固定的。如果报文字节长度不能满足条件,如规定长度是1024字节,但是实际需要发送的内容只有900个字节,那么不足的部分可以补充0。因此定长协议可能会浪费带宽。
  • 接收方,每读取到固定长度的内容时,则认为读取到了一个完整的报文。

提示:Netty中提供了FixedLengthFrameDecoder,支持把固定的长度的字节数当做一个完整的消息进行解码

3.2 特殊字符分隔符协议

在包尾部增加回车或者空格符等特殊字符进行分割 。例如,按行解析,遇到字符n、rn的时候,就认为是一个完整的数据包。对于以下二进制字节流:

  1. +--------------+ 
  2.    | ABCnDEFrn | 
  3.    +--------------+ 

那么根据协议,我们可以判断出来,这里包含了2个有效的请求报文

  1. +-----+-----+ 
  2.    | ABC | DEF | 
  3.    +-----+-----+ 

在特殊字符分隔符协议中:

  • 发送方,需要在发送一个报文时,需要在报文尾部添加特殊分割符号;
  • 接收方,在接收到报文时,需要对特殊分隔符进行检测,直到检测到一个完整的报文时,才能进行处理。

在使用特殊字符分隔符协议的时候,需要注意的是,我们选择的特殊字符,一定不能在消息体中出现,否则可能会出现错误的拆包。例如,发送方希望把”12rn34”,当成一个完整的报文,如果是按行拆分,那么就会错误的拆分为2个报文。一种解决策略是,发送方对需要发送的内容预先进行base64编码,由于base64编码只包含64个字符:0-9、a-z、A-Z、+、/,我们可以选择这64个字符之外的特殊字符作为分隔符。

提示:netty中提供了DelimiterBasedFrameDecoder根据特殊字符进行解码。事实上,我们熟悉的的缓存服务器redis,也是通过换行符来区分一个完整的报文。

3.3 变长协议

(编辑:西安站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读