TCP是一个"流"协议,没有边界的一段数据.像打开自来水管同样,连成一片,没有边界.设计
TCP协议并不了解上层的业务在作什么东西,有什么含义,它会根据本身的缓冲区的实际状况进行数据包的划分.图片
因此,一个完整的数据包可能会被拆分红多个数据包包进行发送,也有可能将不少个数据包变成一个大的数据包发送.it
这就是TCP的粘包和拆包问题.程序
假设客户端分别发送两个数据包D1和D2给服务端.因为服务端一次读取到的字节数不肯定,可能存在4种状况.im
(1)服务端分别接收到 D1 和 D2.没有拆包和粘包.数据
(2)D1和D2包被一次接收了(粘包)客户端
(3)D1包被一次接收,D2包被分两次接受(拆包)协议
(4)D1和D2都被拆开,分两次读取完成.img
(5)D1和D2被拆分N个,分N次读取完成.服务端
查阅资料后找到了为何会发生以上的缘由:
(1)程序的写入的字节大于发送数据的缓冲区大小(我只看懂了这个)
(2)进行MSS大小的TCP分段
(3)以太网帧的payload大于MTU进行IP分片
2和3表示看不懂啊.
** 一般的解决方案**
TCP是不知道上层的业务数据的.因此在底层没法保证不发生粘包拆包,这个问题只能经过上层应用协议栈的设计来解决.
(1)消息定长,固定大小,不够空格补位(5楼不辅助,你懂的,要学会补位.)
(2)包尾增长回车符,进行分割
(3)将消息分为消息头和消息体,消息头里来标识消息总长度.