TCP粘包问题

一、粘包问题

  • 首先要明确,粘包问题中的“包”,是指的应用层的数据包
  • 在TCP的协议头中,没有如同UDP一样的“报文长度”字段,但是有一个序号字段
  • 在传输层角度来看,TCP是一个一个报文过来的,按照序号拍好序,放在缓冲区中
  • 在应用层的角度,看到的只是一串连续的字节数据,所以应用层不知道从哪个部分开始,是一个完整的数据包

     从缓冲区来看,后一包的数据的头部紧挨着前一包数据的尾部,使得接收方不能准确的读取一包数据,也就是接收方多读或者少读一包数据所造成的现象就是粘包现象,粘包问题只会发生在TCP的长连接时,因为TCP是面向字节流,以流的方式处理数据,当长连接时才有可能多个数据包连接在一起的情况,UDP是面向数据包的,有固定的消息边界.

二 、为什么会出现粘包

      粘包问题既可能是发送方需要等待缓冲区满了之后才发送数据造成的;也有可能是接收方来不及接收缓冲区的包,造成多个包一起接收的现象

  • 发送端造成的粘包:粘包是由TCP协议本身造成的,TCP协议为了提高传输效率,发送方往往要收集足够多的数据才发送出去,若是连续几次发送的数据都很少,通常TCP会根据算法把这些数据合成一个包然后发送出去,这样接收方就会出现粘包
  • 接收方造成的粘包:接收方会把发送方的数据先放到缓冲区当中,应用程序再从缓冲区中读取数据,若是下一个包数据到达时前一包数据没有被取走,则下一包数据就粘在前一包的尾部,应用程序根据预先设定的缓冲区的大小从系统设定的缓冲区中读取数据,这样就一次体取了多个数据包

三、怎么避免粘包

归根结底就是:明确俩个包之间的边界

  • 对于定长的包,保证每次都按照固定大小来读取即可
  • 对于变长的包,可以在包头的位置,约定一个包总长度的字段从而就知道包的结尾位置
  • 对于变长的包,还可以在包和包之间使用明确的分隔符(应用层协议,就是程序员自己定义的)

应用层协议--HTTP避免粘包的三种方式:

  1. 使用回车换行符作为分隔,也就是以空行作为消息报头的结束.
  2. 以固定的方式读取消息报头,http消息报头中的每一行都是一个完整的内容
  3. 给出数据包的大小,按照大小读取,http的消息报头中有一个Content_Length字段来标记消息正文的大小

所以HTTP协议至少有三种方式来避免粘包

  1. 添加分隔符,来标识一个包的开始和结束
  2. 发送方将数据结构化,接收方按照结构来读取
  3. 发送方在发送的时候,在首部加上数据报的大小,接收方在接收的时候先解析出大小,在按照大小读取

思考: 对于UDP协议来说,是否也存在"粘包问题"?

  • 对于UDP,如果还没有上层交付数据,UDP报文长度依然在,UDP是一个一个把数据交付给应用层,就有很明确的数据边界
  • 站在应用层的角度,使用UDP协议时,要么收到完整的UDP报文,要么全都不收,不会出现"半个"的情况

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值