计算机网络(9) TCP超时重传以及滑动窗口流量控制

一.确认机制与流量控制

引用:滑动窗口,TCP的流量控制机制 | 小菜学网络

确认机制

由于 IP 协议缺乏反馈机制,为保证可靠性,TCP 协议规定:当接收方收到一个数据后,必须回复 ACK 给发送方。这样发送方就能得到反馈,如果数据发出去后很长时间都没有收到 ACK 确认,说明数据很有可能已经丢失了。

一旦数据在传输过程中丢失,发送方必须重传。因此,TCP 每次发送数据后,都会启动一个定时器。如果定时器超时还没收到对方确认,TCP 就会重新发送数据。我们来看一个例子:

图中左边是发送方待发送字节流状态,字节流中每个字节都有一个序号,假设从零开始。数据颜色代表发送状态:

  • 灰色,表示已经发出去而且收到对方确认的数据;
  • 蓝色,表示已经发出去但还未收到确认的数据;
  • 绿色,表示还未发送的数据(包括未来要发但此刻还不存在的数据);

刚开始时,发送方已经成功发送了前 5 个字节,如灰色部分所示。随后它开始发送数据①,其实序号为 5 ,总共 5 个字节。再啰嗦一句,起始序号 5 保存在 TCP 报文段中的序号字段;而数据长度 5 无须保存,TCP 可以根据 IP 包数据长度和 TCP 头部长度来计算。

发送方在发送数据的同时,启动了一个计时器。这些数据虽然已经发送出去了,但还没收到对方确认,因而处于蓝色状态。随后它收到接收方发来的确认,状态转为灰色,万事大吉!注意到,确认号是最后一个字节加一,也就是下一个数据的起始序号。

紧接着,发送方又发出了数据②,首字节序号为 10 ,总共 4 个字节。这次比较背,数据②在传输过程中丢失了!发送方等到计时器超时都没收到确认,因此它将数据重新发送一次,并再次启动计时器。

这时,数据②仍维持蓝色不变,因为发送方还没收到确认。等数据成功送达对方,并收到对方的确认后,数据转成灰色状态。待发送字节流颜色不断交替,滚滚向前。

接收缓冲区

由于承载 TCP 报文段的 IP 包是独立路由的,可能走不同的网络路径,无法保证一定按照发送顺序送达目标主机。 TCP 协议需要向上提供连续字节流传输服务,如果报文段错序到达,TCP 必须根据序号重新排列数据。

另一方面,数据到达后目标主机后,接收方应用程序可能忙于其他事情,无法及时处理。鉴于这两个点,TCP 接收方需要在内存中准备一个接收缓冲区,用于临时保存数据。

TCP 报文段到达后,数据先临时保存在缓冲区中,位置由序号决定。当相邻的数据均达到后,组成连续字节流提交给应用程序。当应用程序将数据取走后,缓冲区中的副本就可以删除。如果应用程序忙于其他任务,数据则继续缓存在缓冲区中。

TCP 协议一般由操作系统内核实现,应用程序只需通过系统调用发送/接收数据,完全不用关心序号或 ACKTCP 数据到达后,内核先将其保存于接收缓冲区,再通知应用程序读取。

我们来看一个新例子,这次站在接收方的角度,考察数据流在接收缓冲区中的状态:

  1. 刚开始时,接收方缓冲区已接收了 5 字节数据,但应用程序尚未读取;
  2. 发送方又发来 5 字节数据,接收方回复 ACK ,数据保存在缓冲区,应用程序仍未读取;
  3. 与此同时,接收方通告窗口大小为 5 字节,表示自己还能接收 5 字节数据(超过缓冲区就会溢出);
  4. 应用程序将缓冲区中的 10 字节数据全部读取,接收方通告新窗口大小为 15 字节;
  5. 发送方又前后发来两份数据,分别是数据②和数据③,大小均为 4 字节;
  6. 其中,数据②在网络中丢失了;
  7. 数据③顺利到达,接收方根据序号将其保存在缓冲区中,并回复 ACK ,确认号和窗口均不变;
  8. 由于数据②尚未到达,未能组成连续数据提交给应用程序;
  9. 因长时间没收到 ACK ,发送方重传数据②(数据③也被重传,因为 ACK 只确认 10 以前的数据);
  10. 数据②顺利到达,接收方将其保存在缓冲区中,并回复 ACK (注意确认号,数据③也一并确认了);
  11. 数据②和数据③组成连续数据,可以提交给应用程序读取;

综上所述,接收缓冲区主要起到两个关键作用:

  • 应用进程繁忙时暂存数据
  • 数据乱序到达时重排数据

流量控制

接收缓冲区大小是有限的,如果应用进程处理缓慢,发送方还拼命发送,最终肯定会压垮接收方。因此,当缓冲区有变化时,接收方应该通过 窗口大小 字段,将它的剩余大小告知发送方。

接收方通告的窗口大小通常称为 通告窗口advertised window ),可缩写为 awnd 。它起到约束发送方发送速度的作用:

  • 如果接收方应用进程繁忙,迟迟未读取缓冲区里的数据,那么窗口大小将慢慢变小;
  • 当窗口大小降为零,发送方就停止发送新数据;

通过通告窗口,发送方可以实时感知接收方缓冲区的状态,然后根据缓冲区剩余空间动态调整发送速度,这就是 TCP流量控制flow control )机制。

滑动窗口

重新站在发送方的角度,来考察数据的发送状态,可以分为四种:

  1. 已发送且已确认,这部分已经发送完毕,可以忽略;

  2. 已发送但未确认,这部分可能在网络中丢失,数据必须保留以便必要时重传;

  3. 未发送但可发送,这部分接收方缓冲区还有空间保存,可以发出去;

  4. 未发送且暂不可发送,这部分已超出接收方缓冲区存储空间,就算发出去也没意义;

注意到,第②和第③部分加起来就刚好是接收方缓冲区大小,如图红框部分。红框的左边缘由接收方的最后一个 ACK 确认决定,而长度由接收方通告的窗口大小决定,它规定了当前发送方能发送的最大数据量。

当发送方收到对方的 ACK ,意味着有数据已成功到达接收方,窗口左边缘将向右移动:

当接收方应用进程将数据从缓冲区取出后,向接收方通告新的窗口大小,这时窗口右边缘向右扩张:

随着双方通信的进行,由 已发送但未确认 以及 未发送但可发送 这两部分数据组成的窗口将不断向右移动,因此被形象地称为 滑动窗口sliding window ),TCP 流量控制机制也因此被称为滑动窗口机制。

二.CS144关于Slide Window的讲解

使用停止-等待算法进行单包传输的缺点:假设通信最大带宽为10Mbyes/s,RTT = 50ms。则每秒可以发送20个数据包,假设链路层使用以太网传输。一个包最多有12Kbit数据,则每秒最多可以传输240Kbit数据约等于30KBytes约等于带宽的百分之3左右。

故而使用停止等待算法传输数据,无法达到最大传输带宽,带宽利用率极低。

解决方案(滑动窗口):

滑动窗口允许在等待时间内(Flight Time)连续发送多个包,当窗口长度够大时,理论可以达到传输的最大带宽。

停止等待与滑动窗口两种流控制算法示例如下:

发送端滑动窗口:

每个发送段落都有一个序列号。发送端滑动窗口维护三个变量,一个是窗口长度SWS(由接收端缓存区剩余长度决定),一个是 LAR最后一次接收确认ACK(主要决定窗口起点),最后一个是最后一个发送序列的序列号LSS。满足(LSS - LAR)<= SWS,也就是说最后一次发送的序列减去窗口左边界必须小于窗长。

LAR是运行时变化的,故而窗口是可以移动的。

当接收缓存区中元素被取出时,可以通知发送端滑动窗口长度增加,增大发送速率。

接收端滑动窗口维护三个变量。RWS即为接收窗口长度(接收缓冲区),LAS允许接收的最后一个序列号,LSR最后一次接受的序列号。并且满足(LAS - LST) <= RWS 。

例如:RWS = 5, LSR = 3(窗口左边界)。那么可以继续接收序列号为4 5 6 7 8 9的数据。

如果小于最大可接收边界则发送ACK回复发送端

此时ACK采用累积和的形式。

相关推荐
小蜗牛慢慢爬行30 分钟前
有关异步场景的 10 大 Spring Boot 面试问题
java·开发语言·网络·spring boot·后端·spring·面试
MARIN_shen35 分钟前
Marin说PCB之POC电路layout设计仿真案例---06
网络·单片机·嵌入式硬件·硬件工程·pcb工艺
打鱼又晒网1 小时前
linux网络套接字 | 深度解析守护进程 | 实现tcp服务守护进程化
linux·网络协议·计算机网络·tcp
m0_748240021 小时前
Chromium 中chrome.webRequest扩展接口定义c++
网络·c++·chrome
終不似少年遊*1 小时前
华为云计算HCIE笔记05
网络·华为云·云计算·学习笔记·hcie·认证·hcs
蜜獾云2 小时前
docker 安装雷池WAF防火墙 守护Web服务器
linux·运维·服务器·网络·网络安全·docker·容器
小林熬夜学编程3 小时前
【Linux网络编程】第十四弹---构建功能丰富的HTTP服务器:从状态码处理到服务函数扩展
linux·运维·服务器·c语言·网络·c++·http
Hacker_Fuchen3 小时前
天融信网络架构安全实践
网络·安全·架构
上海运维Q先生3 小时前
面试题整理15----K8s常见的网络插件有哪些
运维·网络·kubernetes
ProtonBase3 小时前
如何从 0 到 1 ,打造全新一代分布式数据架构
java·网络·数据库·数据仓库·分布式·云原生·架构