[关闭]
@Awille 2021-09-29T13:39:45.000000Z 字数 3719 阅读 168

TCP的那些事

计算机网络 TCP


1、TCP的头格式

image.png-97.8kB

4个字节为1行
source port(0-1) destination port(2-3)
sequence number(0-3)
acknowledgement number
offset reserved TCP Flags windows(滑动窗口相关,接收端告诉发送端自己的TCP缓冲区大小,2 bytes大小,16bit,最大65535字节,最大可扩展为31bit)
checksum urgent pointer

2、三次握手

2.1、握手过程

2.2、为什么三次握手

主要是初始化sequence number的初始值,SYN(sychronize sequence number),序列号要作为之后通讯的序号,解决传输乱序的问题

2.3、SYN超时

如果SYN发出后,服务端返回ACK-SYN标志位后客户端掉线未回应,服务端会重发SYN-ACK,linux默认重试次数为5次,分别是1s,2s,4s,8s,16s总共31s,第五次发出后还要等待32s才知道第五次超市,所以总共需要63s才能把连接断开。SYN FLOOD攻击就是基于此原理,客户端发个SYN报文就下线。

3、四次挥手

image.png-108.9kB

3.1 四次挥手过程

image.png-262kB

3.2 为啥四次挥手

要保证双方都关闭了连接。因为TCP是全双工的。

另外,在建立连接时,服务器可以把SYN和ACK放在一个包中发送。
  但是在断开连接时,如果一端收到FIN包,但此时仍有数据未发送完,此时就需要先向对端回复FIN包的ACK。等到将剩下的数据都发送完之后,再向对端发送FIN,断开这个方向的连接。
  因此很多时候断开连接时FIN和ACK需要在两个数据包中发送(当server也没有数据要发送了,FIN和ACK是可以放在一起发送的),因此需要四次握手
  

3.3 为啥time wait 2msl

4、TCP重传机制

TCP重传机制好文章

4.1、超时重传机制

在发送与1个数据之后,就开启一个定时器,若是在这个时间内没有接收到数据接收方回传的ACK确认报文,就对该报文进行重传,在达到一定次数还没收到ACK就发就发送一个复位信号。定时器(RTO)时间根据网络中的RTT(数据从网络一端传到另一端的时间,包含往返)来自适应调整。
接收端没有收到对应的报文,不会回ACK,发送方死等对应报文ACK,发现超时后进行重传。RTO时间应该略大于RTT(Round Trip Time),RTO过长,效率低,RTO过于短,重发的快,容易造成网络拥塞。RTO时间应该是随着RTT时间动态变化的。

4.2、快速重传机制

不以时间驱动,而以数据驱动。如果接收端没有收到期望的数据,接收到乱序的数据就给发送端回复ACK,回复重复相同的ACK,三次以后出发快速重传。对于该重传机制,发送端还是不知道重传单个丢失的报文,还是重传包括单个丢失报文及以后所有的报文。

4.3、SACK 选择重传机制

image.png-237.8kB
在快速重传的基础上,返回最近收到的报文段的序列号范围。

4.4、Duplicate SACK

重复ACK在SACK的基础上,携带额外信息,告诉发送饭有哪些数据包自己重复接受了,帮助发送方判断是不是发生了包时序,ACK丢失,包重复或伪重传,让TCP可以更好的做好网络流控。
* 发送方确认是不是ACK丢包
* 是不是发送方的数据包被网络延迟延迟了。

5、TCP滑动窗口(Sliding Window Protocol)

用于网络数据传输时的流量控制,避免拥塞的发生。该协议允许发送方在停止并等待确认前发送多个数据分组。滑动窗口大小本质上是发送方根据接收方缓冲区区大小进行确认。
ACK包含两个重要的信息,一是代表接收方希望接受的下一个字节序号n,发送n代表前n-1的字节都已经收到;二是当前的窗口大小m,根据这两个信息,假设发送方已经发送到第x字节,则可以发送的字节数就是y=m-(x-n)
发送方滑动窗口:
* 已发送并已确认|已发送但未确认|未发送但已准备发送(接收方有空间)|未发送且不可发送(接收方没有空间)
接收方滑动窗口:
* 已接受|未接收住准备接受|未接受并未准备接受

6、拥塞控制

6.1、拥塞窗口

6.2、为什么要有拥塞控制

首先要明白拥塞控制与流量控制有什么不同,流量控制考虑的是单纯的发送方与接收方,这两个在全部网络过程中的两个端点。而拥塞控制考虑的是整个网络。可以想象一下,在流量控制当中,接收方跟发送方考虑的只是自己的报文有没有发送并且被接收的问题,假设现在网络阻塞,在超时重传机制当中,发送方没有发送后在计时器时间内没有接收到确认报文,就立马重新发送报文,这时候对已经拥塞的网络来说,无异于雪上加霜。同样实在拥塞的网络情况下,考虑下快速重传机制,同样是这个道理。所以,针对以上问题,TCP应该要有一个拥塞控制机制,不然,后果不堪设想。

在拥塞控制机制当中,发送方会维护一个滑动发送窗口,该窗口与拥塞控制窗口一般是一样大的,除非受到物理限制,假设网络的承载量是无线的,那么拥塞窗口理论上就可以无线增大,但受现在电脑技术限制,我们可能无法将发送窗口与拥塞窗口变得一样大。

6.3、拥塞控制流程

cwnd:拥塞窗口大小

ssthreshold: 拥塞阈值 (该阈值是对网络状况的一个预估,决定在拥塞窗口多大的时候采取怎样的策略,它的初始化一般是一个估计,一般都会给出)

a、慢启动

此时一般是(记住是一般情况)cwnd

b、拥塞避免

此时一般cwnd>ssthreshold,此时cwnd呈线性增长,32、33、34、35...这种增长趋势

c、拥塞解决

此时一般是遇到了网络拥塞的状况,解决方法是拥塞阈值乘性减即ssthreshold=cwnd/2,cwnd=1,或者ssthreshold=cwnd/2,cwnd=ssthreshold,这两种情况在后面说明

d、快速恢复

一般是启用拥塞结局策略之后,根据不同的情况,进入慢启动或者拥塞避免阶段。

下面我们模拟一下发送方发送报文:假设ssthreshold=8

首先肯定是慢启动阶段,cwnd增长,1、2、4、8,到8的时候,cwnd达到了ssthreshold的值,于是进入拥塞避免阶段,cwnd继续增长8、9、10,假设到10的时候,发生了网络拥塞,这时候拥塞分为两种情况:

第一种,发送方接收到同一序列号的报文的连续三个ACK确认报文,说明出现了丢包,但是接收到接收方发送的丢包信号,说明网络情况还是相对较好的,于是此时发送方做出反应,将ssthreshold=cwnd/2=5,cwnd=ssthreshold=5,然后进入拥塞避免阶段,cwnd继续以5、6、7....这种情况增长。

第二种,发送方接收到同一序列号的报文连续两个ACK确认报文,这时候,就说明网络拥塞情况就比较严重了,连接收方发送的丢包信号都不完整了,这个时候得采取更加严厉的措施了,于是ssthreshold=cwnd/2,cwnd=1,然后重新进入慢启动过程。

7、TCP粘包

TCP粘包问题

7.1、粘包发生场景:

因为TCP是面向流,没有边界,而操作系统在发送TCP数据时,会通过缓冲区来进行优化,例如缓冲区为1024个字节大小。

如果一次请求发送的数据量比较小,没达到缓冲区大小,TCP则会将多个请求合并为同一个请求进行发送,这就形成了粘包问题。

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

7.2、Nagle算法

Nagle算法好文
* 为什么会发生,与TCP的Nagle算法相关?
在使用一些通讯协议的时候,比如telnet会有一个字节发送的场景,每次发送一个字节的数据,会有产生41个字节的分组,20个字节的IP
HEADER与20个字节的TCP HEADER,这样传输一个字节的时候就要浪费掉40个字节的头部信息,这是一笔巨大的开销,这也会加剧网络拥塞。该问题也是SMALL PACKET PROBLEM。

8、TCP与UDP的区别

8.1、UDP

image.png-24.1kB

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注