计算机网络期末复习笔记(并不犯困版+大白话版)-第五章 传输层

复习笔记目录

前期理解:

等会我们要学的 网络层,是主机之间的通讯;

而 传输层 是指:端口到端口,进程到进程的。

主要讲几个内容:

1.运输层是啥

2.运输层最重要的两大协议udp和tcp

3.tcp三次握手和四次再见

4.TCP 可靠传输、流量控制与拥塞控制

可靠传输包括:停止等待协议,超时重传机制,滑动窗口机制

流量控制:动态控制剩余窗口大小,死锁以及死锁的解决方法------持续计时器

拥塞控制:慢开始算法(翻倍)、拥塞避免算法(线性)、严重网络拥塞(重传定时器超时)、轻微网络拥塞(3个重复确认->快恢复算法)


一、 运输层基本概念

  1. 作用 :运输层提供应用进程之间的逻辑通信。

  2. 端口(Port):标识主机中的应用进程。长度为 16 位,可表示 0~65535 个端口号。

    • 熟知端口号:0~1023(如 FTP 21, DNS 53, HTTP 80)。

    • 登记端口号:1024~49151。

    • 客户端口号:49152~65535(通信时动态分配)。

  3. 两大协议

    应用层使用了很多协议,但是他们在运输层也都有与之对应的两大核心协议:

    应用层送来报文:udp是把要寄送的报文直接扔过去,而tcp是仔细打包成一个个报文段再送过去

    • UDP(用户数据报协议) :无连接、不可靠信道、面向报文、首部开销小(8字节)。

    • TCP(传输控制协议):面向连接、全双工通信可靠信道、面向字节流、首部至少 20 字节。

      TCP特点 UDP特点
      面向连接,可靠 无连接,不可靠
      传送的数据单位协议是 TCP 报文段 (segment)。 传送的数据单位协议是 UDP 报文或用户数据报。
      接收到报文后需要确认 接收到报文后不需要确认
      面向字节流,应用程序和 TCP 的交互是一次一个数据块(流) 面向报文,报文既不合并也不拆分,一次交付一个完整的报文
      每一条 TCP 连接只能是点对点的(单播通信) 支持单播、多播、广播
      有拥塞控制 没有拥塞控制
      开销大 开销小

二、 UDP 协议(常考结构与检验和)

  1. 特点:支持一对一、一对多、多对一和多对多。不保留边界,不进行拥塞控制。

  2. UDP 首部格式(固定 8 字节:4个字段,每个 2 字节)

    • 4个字段: 源端口 | 目的端口 | 长度 | 检验和

  3. UDP 检验和计算

    • 计算时,要在 UDP 数据报之前临时加上 12 字节的伪首部(包含源 IP、目的 IP、全0字段、IP 协议号号17、UDP 长度)。

    • 注意:伪首部仅仅是为了计算检验和,既不向下传送也不向上递交。


三、 TCP 报文段首部核心字段

  • 序号 (seq) :本报文段所发送的数据的第一个字节的序号

  • 确认号 (ack)期望收到的 下一个报文段的第一个数据字节 的序号。

    ack = N,说明到序号 N-1 为止的所有数据都已正确收到。

  • 数据偏移 :指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远(即 TCP 首部长度)。以 4 字节为计算单位。

  • 控制位(最常考)

    • ACK :仅当 ACK = 1 时确认号字段才有效。所以建立连接后必须让 所有传送的报文段的 ACK = 1。

    • RST :当 RST = 1 时,表明 TCP 连接中出现严重差错,必须释放连接然后重新建立。

    • SYN:在连接建立时用来同步序号。

      SYN = 1, ACK = 0 表示这是一个连接请求报文段。

    • FIN:用来释放一个连接。

      FIN = 1 表示此报文段发送方的数据已发送完毕,并要求释放连接。

  • 窗口:允许对方发送的数据量(用来做流量控制)。


四、 TCP 连接管理(三次握手与四次挥手)

1. 三次握手(连接建立)

这个很有意思,或者说我发明的这个理解版本很有意思。

  • 第一次:客户端发送连接请求。

    ------在吗,我要占用 我的第x号 和你说话

    SYN = 1, seq = x(不携带数据,但消耗一个序号)。

    客户端进入 SYN-SENT 状态。

  • 第二次:服务器同意并响应。

    ------在的,好的,我这边占用 我的y号 开始跟你说话,既然你说你刚刚占用了 你的第x号 说话,那你现在就发过来 x+1号 吧。

    SYN = 1, ACK = 1, seq = y, ack = x + 1(不携带数据,消耗一个序号)。

    服务器进入 SYN-RCVD 状态。

  • 第三次:客户端确认。

    ------好的,我发给你我的 x+1号,既然你说你刚刚占用了 你的第y号 说话,那你现在就发过来 y+1 号吧。

    ACK = 1, seq = x + 1, ack = y + 1(如果不携带数据,则不消耗序号)。

    两端进入 ESTABLISHED 状态。

2. 四次挥手(连接释放)
  • 第一次:客户端发起释放。

    ------我不说了(FIN=1),我最后的这句再见占用 我的第 u 号,我准备挂了。

    FIN = 1, seq = u

    客户端进入 FIN-WAIT-1 状态。

  • 第二次:服务器确认。

    ------知道了(ACK=1),我这边占用 我的第 v 号 回复你。既然你说你刚刚占用了 你的第 u 号 说了再见,那下次你如果还要说话,就发过来 u + 1 号 吧(虽然你已经不说了)。

    SYN = 0, ACK = 1, seq = v, ack = u + 1

    服务器进入 CLOSE-WAIT 状态(半关闭状态,客户端闭嘴,但服务器还能继续发剩余数据)。

期间发生的事情 :在半关闭期间,服务器可能又发了大量的剩余数据,把自己的号用光了,等它准备也说再见时,它自身的号已经变成了 w 号

  • 第三次:服务器发完数据,发起释放。

    ------好了,我也全说完了,我也要挂了(FIN=1)。我最后这句再见占用 我的第 w 号 。另外再强调一次,你还是要发过来 你的 u + 1 号

    FIN = 1, ACK = 1, seq = w, ack = u + 1(消耗一个序号)。

    服务器进入 LAST-ACK 状态。

  • 第四次:客户端确认。

    ------好的(ACK=1),用 我的第 u + 1 号 发出这句最后的回复。既然你说你刚刚占用了 你的第 w 号 说了再见,那你现在也可以安心挂了,你下次要是还活着,就发过来 w + 1 号 吧。

    ACK = 1, seq = u + 1, ack = w + 1

    客户端进入 TIME-WAIT 状态(等待 2×MSL 后彻底关闭)。


五、 TCP 可靠传输、流量控制与拥塞控制

一、 可靠传输机制

由两部分组成:停止等待协议、滑动窗口机制(以字节为单位) 和 超时重传机制。

1. 停止等待协议

发送方每发送一个分组,就必须停止发送,等待接收方的确认信号(ACK)。只有收到确认后,才能发送下一个分组。

分三种情况

很明显,这个信道利用率很低

信道利用率:

假设发送方发送一个分组需要的时间(发送时延)为 TD,全双工信道的单向传播时延为 τ,接收方处理并发送确认分组的时间(发送时延)为 TA。

一个完整的发送周期总时间为:

T=TD+2τ+TA

在广域网或长距离通信中,传播时延 τ 往往远大于分组发送时延 TD。

导致分母极大,利用率 U 极低(通常不足 1%)。

为了打破停止等待协议"干等"的限制,引申出了流水线传输方式 ------滑动窗口机制

2. 滑动窗口机制

TCP 的滑动窗口是以字节为单位的。

发送方和接收方都在内存中维护自己的窗口大小。

A. 发送方窗口(根据接收方通知的 rwnd 动态调整大小)

发送方分为四个部分:

  1. 已发送且已收到确认的字节(处于窗口左边界之外,属于安全数据)。

  2. 已发送但尚未收到确认的字节(处于窗口内靠左侧,如果超时未收到确认,这部分必须重传)。

  3. 允许发送但尚未发送的字节(处于窗口内靠右侧,发送方可以立刻将其发送出去)。

  4. 不允许发送的字节(处于窗口右边界之外,必须等待窗口右移)。

  • 窗口移动触发点:只有当接收方发来确认报文,且确认号 ack 大于当前窗口的左边界时,左边界才会向右移动到 ack 的位置,释放出新的允许发送的字节空间。
B. 接收方窗口
  • 按序接收与累计确认:接收方只有在收到连续且按序的字节时,才会向前移动接收窗口。

  • 不按序到达的处理:

    如果发送方发来了序号 1、2、4、5,缺失了 3。

    接收方收到 4 和 5 时,虽然会将其放入缓冲区 存放,但返回的确认号 ack 只能填 3

    (表示:我期望收到第 3 号字节,到 2 为止的数据我都安全收到了)。

    只要 3 没来,接收窗口的左边界绝对不往后移。

3. 超时重传机制(含快重传)
A. 传统超时重传

发送方每发送一个报文段,就会启动一个超时计数器

如果在规定的超时时间(RTO)内没有收到对方针对该报文段的确认,就判定该报文段丢失,强制重新发送该报文段。

B. 快重传(Fast Retransmit)机制 ------ 应对轻微丢包

传统超时重传必须等 RTO 倒计时结束,效率低。

快重传是利用重复确认来实现提前重传的机制。

判断调节:

发送方收到 3 个相同的重复确认,立刻判定 M3 已经丢失,无须等待自己的超时计数器到期,立刻重传 M3 报文段。

  • 触发步骤推演:

    1. 发送方连续发送了 M1, M2, M3, M4, M5, M6 共 6 个报文段。

    2. 传输过程中,M3 意外丢失,但后面的 M4, M5, M6 都安全到达了接收方。

    3. 接收方收到 M4 时,发现中间缺了 M3,按照规定,立刻回发针对 M2 的确认报文(表示:我只要 M3)。

    4. 接收方收到 M5,再次发出针对 M2 的第 1 个重复确认。

    5. 接收方收到 M6,再次发出针对 M2 的第 2 个重复确认。

    6. 随后另一个数据包到达,接收方再次发出针对 M2 的第 3 个重复确认。

    7. 发送方接收到了三个重复确认,快重传

二、 流量控制机制

流量控制是点对点的。

目的是控制发送方的发送速率,防止发送方发送过快,导致接收方的缓冲区溢出。

1. 动态调整窗口(rwnd)
  • rwnd(接收窗口):接收方在每次给发送方回发确认报文时,都会把当前缓冲区剩余的空闲大小(rwnd),填入 TCP 首部的"窗口(Window)"字段中

  • 发送方收到后,会强制将自己发送窗口大小限制在 rwnd 以内。

    如果接收方处理得慢,缓冲区满了,就会在报文里设置 rwnd = 0

    发送方收到 rwnd = 0 后,必须立刻停止发送任何业务数据。

2. 零窗口死锁与持续计时器(Persistence Timer)
  • 死锁产生原因:

    本来接收方缓冲区满了,发送方收到rwnd=0就停止发送了。

    当接收方缓冲区空出来后,会发一个 rwnd = 4000 的通知报文给发送方。

    如果这个通知报文在网络中丢失了,发送方会一直等通知(不敢发),接收方会一直等发送方的回应(不知道通知丢了),通信彻底锁死。

  • 消除死锁:

    1. 只要 TCP 连接的一方收到对方的 零窗口通知(rwnd = 0),就会在本地强制启动一个 持续计时器

    2. 只要持续计时器到期,发送方就会向接收方发送一个 特殊的 1 字节的 零窗口探测报文段。

    3. 接收方在收到并确认这个探测报文时,给出的确认报文重新携带自己最新的 rwnd 值。

    4. 依靠这个定期探测机制,丢失的窗口更新通知会被重新获取,死锁状态被成功打破。

三、 拥塞控制

拥塞控制目的是防止过多的数据注入到整个网络中,导致中间的路由器或链路过载瘫痪。

1. 状态变量
  • cwnd(拥塞窗口):单位通常为 MSS,即最大报文段长度

  • ssthresh(慢开始门限):用于决定何时在"慢开始"和"拥塞避免"两个算法之间进行切换的阈值。

  • 发送方真正的发送窗口上限 = min(cwnd,rwnd)。

    在考试中通常默认 rwnd 足够大,完全由 cwnd 决定。

2. 推演

设定初始状态:cwnd = 1,慢开始门限 ssthresh = 16

① 慢开始算法(Slow-start)指数增长<- cwnd < ssthresh
  • 增长规律:每经过一个往返时间(RTT),cwnd 的大小直接翻倍(指数增长)。

    • 底层数学机理 :发送方每收到一个普通的确认 ACK 报文,就把 cwnd 的数值加 1。在一轮 RTT 内,发出去几个包就会收到几个确认,所以下一轮 cwnd 直接翻倍。
  • 数值变化:起始 cwnd = 1 → 经 1 个 RTT 变 2 → 经 2 个 RTT 变 4 → 经 3 个 RTT 变 8 → 经 4 个 RTT 变 16

  • 切换点:此时 cwnd = 16 达到了 ssthresh = 16 的边界,慢开始算法 转化为 拥塞避免算法。

② 拥塞避免算法(Congestion Avoidance)线性增长<-cwnd > ssthresh
  • 数据增长规律:每经过一个往返时间(RTT),cwnd 只固定加 1(线性增长)。

    • 底层数学机理 :每收到一个确认 ACK,cwnd 仅增加 cwnd1。当整轮窗口的所有包都确认完毕后,刚好增加 1。
  • 数值变化:经 5 个 RTT 变 17 → 经 6 个 RTT 变 18 → 经 7 个 RTT 变 19......一路线性增长到了 24

③ 重新设定门限值减半,cwnd=1 <- 遇到网络严重拥塞:重传定时器超时(Timeout)

cwnd 增长到 24 时,发送方发出去的包触发了超时重传(Timeout)。TCP 判定网络已经瘫痪,执行以下两步:

  1. 重置门限值:将新的慢开始门限 ssthresh 设为当前拥塞窗口的一半,即 ssthreshnew=24/2=12。

  2. 重置拥塞窗口:将 cwnd 强行斩断、直接归 1(cwnd = 1)。

  3. 避免拥塞算法->慢开始算法:

    因为当前 cwnd (1) < ssthresh (12),退回到 慢开始算法,从 1 开始重新翻倍增长(1→2→4→8→12),到了 12 后再进入避免拥塞算法 改成每次加 1。

④ 遇到轻微网络拥塞:快恢复算法(Fast Recovery)<- 3 个重复确认

漏掉了一个包,因而连续触发了前面提到的"3 个重复确认"并引发了快重传。

发送方收到 3 个重复确认后,判定后续其他包仍能安全送达,网络属于轻微堵塞,没必要执行cwmd = 1 的极端惩罚,于是执行快恢复算法:

  1. 重置门限值:同样将新的门限 ssthresh 设为当前拥塞窗口的一半,即 ssthreshnew=12/2=6。

  2. 重置拥塞窗口:让 cwnd 直接等于新的门限值,即 cwnd = 6

  3. 算法转向:由于此时 cwnd 已经等于 ssthresh,慢开始阶段->拥塞避免算法(线性).