如今大家每天浏览网页里的购物网站,使用各种网页工具生活和学习,都使用了网页架构依赖的基础——TCP协议,浏览网页时经常需要输入http网址,而http协议下层协议就是TCP协议,我们在浏览http链接访问到网页时,如果网速正常的话,我们基本不会有数据丢失的感觉,这就是TCP在为我们保驾护航。
TCP在工作中既要保证数据发送的可靠性,又要保证数据发送的效率,也就是单位时间内数据吞吐量,还要减少丢包率,同时要保证低延时。
TCP在我们日常生活中的广泛应用中,它的可靠性保证了我们最核心的诉求之一——数据不会轻易丢失。那么数据在网络中传输,面对日益复杂的通信网络环境,它是怎么保证数据发送和接收顺序的呢?
实际工作中TCP是按照需要的顺序发送数据的,但是,却不能保证接收的顺序就是发送的顺序,如果接收的顺序不对,是怎样恢复到我们想要的顺序的呢,接下来我探讨一下TCP的拆包和粘包
为什么要拆包和粘包
TCP在传输数据时,我们通常是感觉不到的,只知道把需要传输的文件和主机链接传给TCP,它就会把文件发送到我们指定的接收方,那么如果我们给他一个20MB的文件,TCP是一次就传输一个大小20MB的数据包吗,通常受各种条件限制和各种系统工作的限制,TCP会将要传输的文件拆分为适合当下操作系统等受限条件的数据包大小。
那么拆分包的意义是什么呢,当我们运送大批货物时,如果超出一辆卡车的运力,我们就需要用一辆卡车分成很多次把货物从一个仓库运到接收方的仓库,而拆包也是这个道理。数据在网络中传输时,受物理条件,比如我们常说的带宽等的限制,肯定会不断的调整拆包的大小,那么影响拆包大小,或者是否拆包的因素有哪些呢?
- 数据包太大,传输时操作难度大,容易丢失
- 当我们想传输到一台主机数据时,通常网络中是存在并行路径的,拆分为合适的包以后,可以有效利用并行路径,提高传输效率
- 发送数据的缓冲区功能,每台主机的性能是有限的,而且还要处理很多应用的需求,当多个应用同时有发送数据的需求时,主机不可能全部立即响应,这时缓冲区就能帮我们给要发送的数据排队,如果单个包太大,会严重影响缓冲工作的
拆包就是在发送方把大数据拆分成小数据,传送到接收方,再组装起来,具体怎么操作我们后续分析。
当然既然有拆包的需求,那也会有粘包的需求,粘包就是数据包太小,不值得单独发送一次,这时还有其他待传输数据,可以把比较小的数据,放在一起传输到接收方,到达接收方后,我们再拆分为多个数据。
当然,无论拆包还是粘包的过程中,都需要计算出一个合适大小的数据包,我们管这个数据包称为TCP段(TCP Segment)
下面是TCP的主要组成部分
从图中可以看出TCP的主要组成
Source Port:源端口,Destination Port:目的端口
Sequence Number 和 Acknowledge Number 是TCP保证可靠性的,下文描述
Data Offset 是用来标记TCP data 偏移量存在的,根据不同TCP Header的起始字节不同,用本字段来标记
Reserved 保留字段
-
URG/PSH/RST/ACK/SYN/FIN 六个标志位,表示TCP包功能,在介绍三次握手我们有讲过其中用到了ACK、SYN、FIN表示TCP包功能
1. URG 表示紧急需求,当TCP需求紧急操作时,会发送该标记位为1的包,比如远程控制时,如果按下ctrl+C ,TCP就会发送URG标记位为1的包,停止操作 2. PSH 表示三次握手建立连接以后,请求方使用该标志位推送数据 3. RST 表示建立连接以后,如果一方发生异常,会导致另一方接收到异常请求,这时就会发送RST-reset重置当前连接,例如两个主机建立连接后,一方异常关闭,又重启后,继续发送请求,这时另一方就会接收到异常请求,这时就会选择RST来重置当前连接 4. ACK TCP保证可靠性的收到,每次收到任何请求的一方,都要返回ACK标志位,表示收到请求 5. SYN 当一台主机想要建立连接时就好发送SYN给另一台主机,请求建立连接 6. FIN 当主机发送数据任务已完成,想结束连接时,发送FIN结束连接
window 滑动窗口保证可靠性,并控制数据吞吐量
Checksum 校验和算法,一种检验数据是否丢失的算法
Urgent Pointer 因为有时候紧急数据是连续的多个包,需要它来通知接收方进行提前准备
Options 其他字段,例如MSS(maximum segment size)
padding 因为Options长度不固定,需要padding来对齐
MSS(Maximum Segment Size)
MSS是option中可选项,它用来控制TCP段大小,通过协商(Negotiate)来确定的,需要双方共同决定它最终的使用大小。
MSS是实际发送和缓冲区中TCP段的大小,是双方协商得来的,不是那一方决定的。
MSS不能设为太大的值,因为大会影响服务器的内存操作效率,也会占用过多的资源,影响其他用户请求的响应实效。
同时,传输层下层的网络层使用的IP层也会受到影响,如果TCP协议不拆包,那么IP协议就得拆包,因为IP协议受限于网络物理条件的限制,每次传输的包需要在一定限度以下,同时拆分大量的包,会对资源和计算能力提出更高的要求,造成传输效率的延迟。
当然,也不能包越小越好,拆出的包都需要安装协议头,如果包太小,那么协议头就会占据包体积的很大比重,会成为负担,浪费资源利用率,所以,我们需要协商解决包的大小,只有通过协商得到的,才是最优的解决方案。