一个完整的业务可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这个就是TCP的拆包粘包问题。
举个例子:
在现实生活中搬一个大箱子(一个完整的业务)太重了搬不动就只好把大箱子里面的东西分出来挨个进行运输(被TCP拆分成多个包进行发送),再或者东西都很轻且很小,但是也有很多(多个小包)于是把这些个东西打包成一个大包(多个小的包封装成一个大的数据包)进行运输(发送)
原因:
1.应用程序写入数据的字节大于套接字发送缓冲区的大小
(把一个东西(应用程序写入数据的字节)放入箱子中(套接字发送缓冲区的大小),东西比箱子大,放不进去)
2.进行MSS大小的TCP分段。(MSS=TCP报文段长度-TCP首部长度)
MSS官方解释:
MSS(Maximum Segment Size)是TCP数据包每次能够传输的最大数据分段大小。当TCP报文段的长度大于MSS时,就需要进行分段传输。MSS的值一般为MTU值减去IP数据包包头的大小和TCP数据段的包头大小。例如,在以太网上,MSS的值通常是1460字节。如果不设置MSS,则默认值为536个字节。但是,为了提高传输效率,MSS的值最好是512的倍数。TCP报文段的分段与重组是在运输层完成的。
在TCP的三次握手过程中,双方会协商并通告各自期望接收的MSS值。如果一方不接受对方的MSS值,则将使用默认值536字节。但是,MSS值太小或太大都是不合适的。如果MSS值太小,传输一个字节的数据也会消耗较大的开销,效率很低。而MSS值太大,则会增加分片和重组的可能性,增加接收方处理分片包的资源和时间开销。因此,选择合理的MSS值非常重要,应保证数据包不需要分片。在以太网上,MSS可以达到1460字节。
总结来说,MSS是TCP数据包每次传输的最大数据分段大小,它的值应该合理选择,以保证传输效率和避免分片。在以太网上,通常使用1460字节作为MSS的值。
举个栗子:
MSS是TCP数据包每次能够传输的最大数据分段大小。当TCP报文段的长度大于MSS时,就需要进行分段长度。
可以把MSS看作是一个箱子,TCP数据包看作是一个打工人,箱子的容量有限定,因此每次打工人在把东西装到箱子里的时候,都要注意东西是否超出箱子的容量,如果超出来了,超出的部分就要重新再拿一个箱子装起来
3.以太网上的payload大于MTU进行IP分片。
当以太网上的数据包(payload)大小大于MTU(最大传输单元)时,就会发生IP分片。MTU是指一种通信协议的某一层上能通过的最大数据包大小。以太网是一种常见的网络传输介质,其MTU一般为1500字节。如果以太网上的数据包大小超过了这个MTU值,发送端就会将数据包拆分成多个较小的片段进行传输。每个片段都会附上相应的IP首部,以便在接收端重新组装成原始的数据包。这个过程被称为IP分片。通过IP分片,大数据包可以在网络中进行传输,而不受MTU的限制。1
解决方案:
1.消息定长
2.在包尾部增加回车或者空格符等特殊字符进行分割
3.将消息分为消息头和消息尾
4.使用其它复杂的协议,如RTMP协议