网络基础-TCP协议

传输层协议

传输层的作用,TCP协议的特点

报文首部

参考

可靠性传输

TCP可靠性传输的保证:每个已发送的报文都需要进行确认ACK,对等待ACK超时的报文进行自动重传,使用滑动窗口实现连续重传与累积确认以提高信道利用率。

**停止等待:**发送一个报文,则需等待对端对这个报文的确认ACK

**自动重传请求ARQ(Automatic Repeat reQuest):**若等待ACK超时了(每个报文分配一个超时计时器)则重发

**连续ARQ:**使用滑动窗口,对报文进行流水线式的连续发送,并且接收方进行累积确认,只需对按序到达的最后高序号分组发送确认。

**Go-Back-N(回退N)问题:**连续ARQ协议下,若中间报文丢失了,发送方无法知道后面报文段下落,只好把后面的报文也都重传一遍。

**以字节为单位的滑动窗口:**报文首部提供一个窗口大小的字段,用以告诉对端,自己接收窗口的剩余字节大小,让对端据此设置其发送窗口。滑动窗口可以控制发送方的发送速率,保证接收方能够来得及处理到来的数据包,本身有流量控制的作用。

TCP如何处理无解的两军问题

发送方没有收到已发送报文的确认报文时

接收方重复收到已经回应确认的数据时

缓存与窗口

在实现层面上,TCP协议栈中对发送方和接收方分别有一个缓存区,对应发送缓存和接收缓存。他们和发送窗口,接收窗口不是同一个东西,但却有紧密联系。

发送缓存是TCP协议栈中的缓存区,用来接收应用程序传送过来的,并且准备进行发送的数据,同时也包含了那些已发送的但未收到确认的数据。可以认为发送窗口实际上只是发送缓存的一部分。已发送并确认的数据会从缓存中删除。

接收缓存类似。它用来存放已经确认但尚未被应用程序读取的数据,也包含了到达未确认的数据(因累积确认而没来得及确认的或未按序到达的数据)。具体一点,它对应socket套接字缓冲区(SO_RCVBUF),而接受窗口对应这个缓冲区的可用空间。

重传的时机

重传超时时间的大小 --》 加权平均往返时间SRTT与DRTT --》重传报文段对RTT的影响 --》Karn算法 --》 对Karn算法的改进

TCP为每一个报文都设置了一个超时计时器,对超时未收到ACK的报文段进行自动重发。而这个超时重传时间(RTO)的值应该取多大呢?

TCP采用的是一种自适应的算法。

往返时间RTT:报文段发出时间与接收到相应确认时间的时间差。

加权平均往返时间SRTT:又称平滑往返时间,s=smoothed。

$$新SRTT = (1-α) * 旧SRTT + α * (新RTT样本)$$

其中0 ≤ α < 1,TCP采用的值为1/8。内核中的计算公式为:

$$SRTT += 1/8 * (m - SRTT)$$

m为当前RTT。

超时重传时间RTO(RetransmissionTimeOut)应该略大于上述SRTT,TCP规定:

$$RTO = SRTT + 4*DRTT$$

RTTd为RTT的偏差的加权平均值,也就是RTTs与RTT差值的加权平均数,反应了实际RTT与SRTT波动幅度。同样地,依据加权平均数递推式,有:

$$新DRTT = (1-β) * 旧DRTT + β * |RTTs - 新RTT|$$

其中0 ≤ β < 1,TCP采用的值为1/4。

因为无法推断出发送方所收到的确认是对最初报文段的确认还是对重传报文段的确认,所以Karn算法就忽略掉重传报文段的RTT:在计算SRTT的时候,不采用重传报文段的RTT样本。

但是Karn算法会导致RTO无法更新的情况。假如网络波动引起某个时间段内的时延大幅增加,报文段都会超时并重传,这时,Karn算法会忽略掉这些重传报文段的RTT,从而导致RTO无法被更新。

实际上TCP协议是这样处理的:当有报文段发送重传的时候,就将其RTO增加为2*RTO,当不再发生重传时,则按上面所诉的SRTT,RTO的式子计算。

Go-Back-N问题

Go-Back-N问题:由于接收方采用的是累积确认(又称延迟确认,延迟应答),所以无法向发送方反馈中间迟来或丢失报文之后的接收确认情况,使得发送方只能再次发送之后已经收到的数据。为了解决这个问题,TCP协议中提供了一个选择确认(SACK Selective ACK)的机制,它在首部选项字段中增加SACK信息,指明已收到报文段的边界信息。

需要注意的是,选项字段有长度限制,最多40个字节,而一个边界信息就会消耗4字节(一个序号占4字节)。因此,选项字段最多能承载4个边界信息(1字节表示SACK标志位,1字节表示SACK长度,4x4x2=32字节)。

选择确认SACK需要发送方拥有选择重传的能力。

流量控制

滑动窗口机制保证控制发送速率,使得接收方处理 --》零窗口通知(接收窗口=0),持续计时器,零窗口探测报文 --》

流量控制的目的,就是让发送方的发送速率不要太快,要让接收方来得及接收接收。利用滑动窗口机制可以很方便地在TCP连接上实现流量控制。

接收窗口rwnd(receiver window)

TCP首部中有一个窗口大小字段,是接收方用来告诉发送方,自己的接受窗口剩余的字节数大小,让发送方以此来设置发送窗口大小。发送方的发送窗口不能超过接收方给出的接收窗口的数值。

当接收方回复的窗口值为零时,也就是零窗口通知,接收方就会启动一个持续计时器(Persistence Timer),若计时器到期之前,若没有收到恢复窗口(rwnd>0)的通知,则会发送一个零窗口探测报文段。

持续计时器的目的是防止接收方恢复窗口的通知报文段丢失,引起的双方都在死等的问题。

报文段发送的时机

Nagle算法

糊涂窗口综合征

拥塞控制

拥塞控制是一个全局性的问题,而流量控制是一个端到端的通信量控制问题。拥塞控制目的是防止过多的数据注入到网络中,避免发生网络中路由器或者链路的负载持续增加,导致网络过载不可用的情况

拥塞窗口(cwnd, Congestion Window)是一条连接中发送方维持的一个状态变量(u32),值大小

拥塞窗口与发送窗口的联系

我们知道TCP报文段首部中,窗口大小的字段值,是接收方告诉发送方自己能还能接收的数据字节数大小。也就是说,发送方发送窗口的大小不能大于接收方接收窗口的大小。另外,为了保证拥塞控制,发送窗口大小也会受到拥塞窗口的因素。snd_wnd=min(rwnd,cwnd*mss)

慢启动与拥塞避免

快重传与快恢复

Tahoe, Reno与Cubic

BBR

连接管理

三次握手

  • sockets建立,序号同步,窗口协商
  • 历史状态对新连接的影响

四次挥手

  • 全双工?
  • 资源(socket?)释放

连接的有限状态机

其它

携带应答,选择重传机制,

参考


网络基础-TCP协议
http://www.tung7.com/日拱一卒/TCP协议学习.html
Author
Tung7
Posted on
July 3, 2021
Licensed under