U3D网络方面面试:TCP中的粘包、拆包

前言

         TCP是面向字节流(字节流可以理解为一个双向的通道里流淌的数据,这个数据其实就是我们常说的二进制数据,简单来说就是一大堆 01 串。这些 01 串之间没有任何边界的协议,本来就是没有界限的一串数据,不存在什么“粘包”问题。把它称为“包”是为了更好地理解“粘包、拆包”这两种现象。

        TCP开发情况中,“包”可以是TCP在传输的时候封装的报文,分为首部和负载数据;另一种可以说是开发者在应用层封装的报文结构。

为什么要将数据切片

        消息在进入传输层时会被切片位一个个数据包,这个数据包的长度是MSS

        我们的网络可以把它比喻成一个管道,这个管道是有宽度的,这个宽度由链路层提供给网络层,以太网一般认为是MTU(1500字节),如果直接传入这个消息,那么就会超过这个宽度,所以需要切片。

        

  • MTU: Maximum Transmit Unit,最大传输单元。 由网络接口层(数据链路层)提供给网络层最大一次传输数据的大小;一般 MTU=1500 Byte。 假设IP层有 <= 1500 byte 需要发送,只需要一个 IP 包就可以完成发送任务;假设 IP 层有> 1500 byte 数据需要发送,需要分片才能完成发送,分片后的 IP Header ID 相同。
  • MSS:Maximum Segment Size 。 TCP 提交给 IP 层最大分段大小,不包含 TCP Header 和 TCP Option,只包含 TCP Payload ,MSS 是 TCP 用来限制应用层最大的发送字节数。 假设 MTU= 1500 byte,那么 MSS = 1500- 20(IP Header) -20 (TCP Header) = 1460 byte,如果应用层有 2000 byte 发送,那么需要两个切片才可以完成发送,第一个 TCP 切片 = 1460,第二个 TCP 切片 = 540。

什么叫“粘包”

        TCP协议中,发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。

        现在比如说发了两条消息,“巧克力味”和“咖啡”,但是粘包后,变成了“巧克力味咖”和“啡”,“巧克力味”作为上一个包的内容与下一个包的“咖”粘在一起,一起被错误地当成了一个数据包解析了出来。        

        应用层传到 TCP 协议的数据,不是以消息报为单位向目的主机发送,而是以字节流的方式发送到下游,这些数据可能被切割和组装成各种数据包,接收端收到这些数据包后没有正确还原原来的消息,因此出现粘包现象。

        至于拆包,如果一次请求发送的数据量比较大,超过了缓冲区大小,TCP就会将其拆分为多次发送,这就是拆包。

为什么UDP没有粘包?

        粘包拆包问题在传输层、网络层、链路层都有可能发生,日常网络应用开发都在传输层(U3D面试问传输层居多),由于UDP有消息保护边界,不会发生粘包拆包问题,因此只会有TCP发生这两个问题。

 粘包拆包发生场景

正常的理想情况,两个包恰好满足TCP缓冲区的大小或达到TCP等待时长,分别发送两个包;

粘包:两个包较小,间隔时间短,发生粘包,合并成一个包发送;

拆包:一个包过大,超过缓存区大小,拆分成两个或多个包发送;

拆包和粘包:Packet1过大,进行了拆包处理,而拆出去的一部分又与Packet2进行粘包处理。

怎么处理粘包

加入特殊标志

        可以通过特殊的标志作为头尾,比如当收到了0xfffffe或者回车符,则认为收到了新消息的头,此时继续取数据,直到收到下一个头标志0xfffffe或者尾部标记,才认为是一个完整消息。

        采用0xfffffe标志位,用来标志一个数据包的开头,就不怕你发的某个数据里正好有这个内容吗?

        所以一般除了这个标志位,发送端在发送时还会加入各种校验字段(校验和或者对整段完整数据进行 CRC 之后获得的数据)放在标志位后面,在接收端拿到整段数据后校验下确保它就是发送端发来的完整数据。

        

加入消息长度信息

        

        这个一般配合上面的特殊标志一起使用,在收到头标志时,里面还可以带上消息长度,以此表明在这之后多少 byte 都是属于这个消息的。如果在这之后正好有符合长度的 byte,则取走,作为一个完整消息给应用层使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值