TCP知识小结

173 阅读6分钟

重传机制

TCP通过序列号与确认应答实现可靠的传输。

  1. 发送端发送数据(1~1000)
  2. 接收端接收数据后向发送端发送应答(下一个是1001)
  3. 发送端收到应答

超时重传

触发时机:

  1. 数据包丢失。
  2. 确认应答丢失。

超时重传时间(RTO Retransmission Timeout)

RTO时间的影响:

  1. RTO较大,重发就慢,效率回低。
  2. RTO较小,导致没有丢就重发,重发快,增加网络拥塞。

所以RTO应该略大于RTT(数据从发送端发出开始,到收到接收端应答的时间,包的往返时间)

受网络波动的影响,RTO应该是一个动态变化的值:

  1. TCP通过采样RTT的时间,然后进行加权平均,算出一个平滑RTT的值。
  2. 除了采样RTT,还要采样RTT的波动范围。
  3. 如果超时重发的数据再次超时的时候,都会将下一次超时时间间隔设为先前的两倍。

快速重传

不以时间为驱动,而是以数据驱动重传。 当发送端收到了三个ACK = 2的确认知道了Seq还没有收到,就会在超时触发之前,重传丢失的Seq2,但是重传的时候,是重传之前的一个,还是重传所有的问题,于是就有了SACK方法。

SACK

选择性确认(Selective Acknowledgment)

在TCP的头部选项字段里添加一个SACK,他可以将缓存的地图发送给发送方。所以当发送方收到了三次同样的ACK确认报文,于是就会触发快速重发机制,通过SACK信息发现丢失的数据。

滑动窗口

TCP以段为单位,每发一个段进行一次确认应答的处理,包的往返时间越长通信性能就越低,于是引入窗口来解决这个问题。

  1. 窗口内的数据可直接发送,无需等待确认应答。
  2. 在整个窗口的确认应答没有到达之前,如果其中部分数据发生丢包,那么发送端仍要负责重传。
  3. 发送端需要设置缓存保留待被重传的数据,直到收到确认应答。

TCP头里有一个字段Window(也是窗口大小),这个字段时接收端告诉发送端自己还有多少缓冲区可以接收数据,发送端就根据这个接收端的处理能力来发送数据。

SND.WND、SND.UN、SND.NXT

  1. SND.WND:表示发送窗口的大小,大小由接收方决定。
  2. SND.UNA: 是一个绝对指针,它指向的是已经发送但未收到确认的第一个字节的序号。
  3. SND.NXT:是一个绝对指针,它指向的是未发送但可发送范围的第一个字节的序列号。

窗口的实现实际上是操作系统开辟的一个缓存空间,发送方主机再等到确认应答返回之前,必须在缓冲区中保留已发送的数据,如果按期收到确定应答,此时数据就可以从缓存区清除。

流量控制

TCP提供看了一种机制可以让发送方根据接收放的时机接收能力控制发送的数据量,这就是所谓的流量控制。 流量控制

由图可见,发送方根据接收方的窗口大小,动态改变自己窗口大小。

#### 操作系统缓冲区与滑动窗口的关系

发送窗口和接收窗口中所存放的数据都是放在操作系统内存缓冲区中,但这个缓冲区会被操作系统调整。

为了防止这种情况,TCP规定时不允许同时减少缓存又收缩窗口的,而是采用先收缩窗口,过段时间再减少缓存,这样就避免了丢包的情况。

窗口关闭

如果窗口为0时,就会阻止发送方给接收方传递数据,知道窗口变为非0为止,这就是窗口关闭。 当接收方处理完数据后,会向发送方通告一个窗口非0的ACK报文,如果这个ACK报文在网络中丢失了,发送方就会一直等待,造成死锁。

窗口关闭潜在的危险

为了解决这个问题,TCP为每个连接设置一个持续定时器,只要TCP连接一方收到对方的零窗口通知,就启动持续计时器,如果定时器超时就会发送窗口探测报文,而对方在确认这个探测报文时,给出自己现在的接收窗口大小。

序列号与确认应答

sequenceDiagram
Client->>Server: data(1-1000)
Server-->>Client: ACK(确认应答,下一个是1001)
Client-)Server: data(1001-2000)
  1. 客户端发送数据之后会等待服务端应答。
  2. 如果有确定应答,说明数据已经成功到达对端。
  3. 如果客户端在一个特定时间间隔都未收到服务端发来的确认应答,将会对此数据进行重发。
  4. 如果是确认应答丢失,客户端会发相同的数据给服务端,服务端发现数据重复则会丢掉数据。

重发超时的确定

重发超时是指在重发数据之前,等待确认应答到来的那个到来的那个特定时间间隔,如果超过了这个时间仍然未收到确认应答,发送端将进行数据重发。 这个时间间隔需要满足?

  1. 时间尽可能小,减小延迟。
  2. 能够保证确认应答一定能在这个时间内返回。
  3. 随着数据包途径的网络环境不同而有所变化。

于是大致得出一个时间,重发超时 = 往返时延 + 偏差。

异常策略:

  1. 数据被重发后若还是收不到确认应答,则进行再次发送,等待确认应答的时间会以2倍,4倍的指数函数延长。
  2. 达到一定次数后就回判定为网络或对端主机发生了异常。

拥塞控制

在网络出现拥堵时,如果继续发送大量数据包,可能会导致数据包延迟,丢失等,这时TCP就会重传数据,但是一重传就会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这个情况就会进入恶性循环被不断的放大...

拥塞窗口:是发送方维护的一个状态变量,他会根据网络的拥塞程度动态变化。

拥塞算法:

  1. 慢启动
  2. 拥塞避免
  3. 拥塞发生
  4. 快速恢复

当发送方每收到一个ACK,拥塞窗口cwnd的大小就会加1。

  1. 慢启动:拥塞窗口大小按指数进行增长
  2. 拥塞避免:当到达慢启动门限ssthresh后,窗口大小按线性进行增长。

拥塞发送 —— 超时重传

连接管理

三次握手:

sequenceDiagram
Client->>Server: SYN(请求建立连接)
Server->>Client: ACK(针对SYN(请求建立连接)的应答)SYN(请求建立连接)
Client-)Server: ACK(针对SYN(请求建立连接)的应答)

四次挥手:

sequenceDiagram
Client->>Server: FIN(请求断开连接)
Server->>Client: ACK(FIN(请求断开连接)的应答)
Server->>Client: FIN(请求断开连接)
Client-)Server: ACK(FIN(请求断开连接)的应答)

数据段

MSS(最大消息长度)正好是IP中不会倍分片处理的最大数据长度。 TCP在传送大数据时是以MSS的大小将数据进行分割发送。进行重发时也是以MSS为单位。 MSS是在三次握手时被计算得出的。

  1. Client:SYN(请求建立连接)TCP首部将MSS设置为4322.
  2. Server:SYN(请求建立连接)TCP首部将MSS设置为1133.
  3. Client:ACK TCP首部将MSS确定为1133

学习资料

  1. 图解TCP/IP
  2. 某个大佬的文章(文章地址找不见了,我继续寻找,之后更在这里)