计算机网络第五章:传输层学习总结
传输层是计算机网络体系结构中的核心层之一,它负责为运行在不同主机上的应用进程之间提供端到端的逻辑通信。本章主要围绕用户数据报协议(UDP)和传输控制协议(TCP)展开。
I. 传输层服务
传输层提供应用进程之间的逻辑通信,而非主机之间的物理通信(这是网络层的工作)。
1. 进程到进程通信 (Process-to-Process Communication)
- 概念:传输层提供的是应用进程之间的通信,而不是主机之间的通信。这意味着数据从一台主机的某个进程发送到另一台主机的某个进程。
- 实现 :通过端口号 (Port Number) 来标识主机上的特定应用进程。
2. 复用与分用 (Multiplexing and Demultiplexing)
- 复用 (Multiplexing):发送方在传输层将多个应用进程的数据封装成报文段,然后将这些报文段交给网络层。
- 分用 (Demultiplexing):接收方在传输层从网络层接收到数据报后,根据报文段中的端口号将数据交付给目标应用进程。
3. 端口号 (Port Number)
- 概念:一个16位的数字,用于标识主机上的应用进程。范围从0到65535。
- 分类 :
- 熟知端口 (Well-known Ports):0 ~ 1023。由IANA(Internet Assigned Numbers Authority)指定,用于一些常用的服务,如HTTP (80), FTP (21), SMTP (25), DNS (53) 等。
- 注册端口 (Registered Ports):1024 ~ 49151。可由用户进程使用,但需要向IANA注册,以避免冲突。
- 动态/私有端口 (Dynamic/Private Ports):49152 ~ 65535。客户端进程通常使用这些端口与服务器进行通信,这些端口是临时分配的。
II. 用户数据报协议 UDP (User Datagram Protocol)
UDP 是一种无连接、不可靠的传输层协议,提供尽力而为的服务。
1. 特点
- 无连接 (Connectionless):发送数据前无需建立连接。
- 尽力而为 (Best-Effort):不保证可靠传输,不提供数据包的顺序、完整性或重复性保证。
- 无拥塞控制 (No Congestion Control):不对网络拥塞做出反应,会持续发送数据,可能加剧拥塞。
- 无流量控制 (No Flow Control):不控制发送方的发送速率。
- 首部开销小 (Small Header Overhead):只有8字节的固定首部。
- 面向报文 (Message-Oriented):UDP 对应用层交下来的报文,不合并,不拆分,保留报文的边界。
2. UDP 首部格式
UDP 首部只有四个字段,每个字段2字节(16位):
- 源端口 (Source Port):发送方进程的端口号。
- 目的端口 (Destination Port):接收方进程的端口号。
- 长度 (Length):UDP 用户数据报的长度(首部 + 数据),最小值为8字节。
- 校验和 (Checksum):用于检测 UDP 用户数据报在传输过程中是否有错。
3. 伪首部校验和 (Pseudo-header Checksum)
- 目的:UDP 校验和计算时会使用一个"伪首部",它不是 UDP 报文段的真正首部,仅在计算校验和时临时添加。
- 内容:伪首部包含源IP地址、目的IP地址、协议(UDP为17)、UDP长度。
- 作用:通过包含IP地址信息,可以检测出是否将UDP数据报错误地交付给了目的主机上的错误进程。
III. 传输控制协议 TCP (Transmission Control Protocol)
TCP 是一种面向连接、可靠的传输层协议,提供全双工通信。
1. TCP 报文段格式
TCP 报文段是 TCP 传输的数据单元,其首部至少20字节。
- 源端口 (Source Port):16位,发送方进程的端口号。
- 目的端口 (Destination Port):16位,接收方进程的端口号。
- 序号 (Sequence Number, Seq):32位,本报文段所发送数据的第一个字节的序号。
- 确认号 (Acknowledgment Number, Ack) :32位,期望收到对方下一个报文段的第一个字节的序号。若确认号为 NNN,则表明 N−1N-1N−1 之前的所有数据都已正确收到。
- 数据偏移 (Data Offset):4位,表示TCP报文段首部长度,以4字节为单位。
- 保留 (Reserved):6位,保留,目前全为0。
- 标志位 (Flags) :6位,每个位代表一个控制功能:
- URG (Urgent):紧急指针有效。
- ACK (Acknowledgment) :确认号字段有效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置1。
- PSH (Push):急迫位,要求接收方尽快将数据交付给应用层。
- RST (Reset):复位连接,通常表示连接出现严重错误。
- SYN (Synchronize):同步序号,用于建立连接。当 SYN=1, ACK=0 时表示连接请求;当 SYN=1, ACK=1 时表示同意连接。
- FIN (Finish):终止连接,用于释放连接。
- 窗口大小 (Window Size):16位,接收方告知发送方自己还能接收多少字节的数据,用于流量控制。
- 校验和 (Checksum):16位,对整个TCP报文段(首部+数据)进行校验。计算时也使用伪首部。
- 紧急指针 (Urgent Pointer):16位,当 URG=1 时有效,指出紧急数据在报文段中的偏移量。
- 选项 (Options):长度可变,如最大报文段长度 (MSS)、窗口扩大选项、时间戳选项等。
2. 可靠传输机制
TCP 通过多种机制确保数据可靠传输:
- 面向字节流 (Byte Stream):TCP 将应用层数据视为一串无结构的字节流,不保留报文边界。
- 滑动窗口协议 (Sliding Window) :
- 发送窗口 (Send Window):发送方维护的一个窗口,表示允许发送但尚未确认的数据范围。
- 接收窗口 (Receive Window):接收方维护的一个窗口,表示期望接收的数据范围。
- 窗口大小动态变化,用于流量控制和拥塞控制。
- 累积确认 (Cumulative Acknowledgment):接收方只需确认它已收到的数据中按序的最后一个字节,表明该字节之前的所有数据都已收到。
- 重传机制 (Retransmission) :
- 超时重传 (Timeout Retransmission):发送方为每个已发送但未确认的报文段设置一个定时器。若定时器超时仍未收到确认,则重传该报文段。
- 快速重传 (Fast Retransmit):当发送方收到3个重复的 ACK 报文时,不等待定时器超时,立即重传丢失的报文段。这通常意味着网络中可能只丢失了一个报文段,而不是发生严重拥塞。
3. 连接管理
TCP 是面向连接的协议,连接的建立和释放都需要经过特定的握手过程。
(1) 三次握手 (Three-way Handshake) - 建立连接
- SYN_SENT :客户端发送 SYN 报文段(
SYN=1, Seq=x),进入SYN_SENT状态。 - SYN_RCVD :服务器收到 SYN 报文段后,发送 SYN+ACK 报文段(
SYN=1, ACK=1, Seq=y, Ack=x+1),进入SYN_RCVD状态。 - ESTABLISHED :客户端收到 SYN+ACK 报文段后,发送 ACK 报文段(
ACK=1, Seq=x+1, Ack=y+1),进入ESTABLISHED状态。服务器收到此 ACK 报文段后也进入ESTABLISHED状态。
(2) 四次挥手 (Four-way Handshake) - 释放连接
- FIN_WAIT_1 :客户端发送 FIN 报文段(
FIN=1, Seq=u),表示不再发送数据,进入FIN_WAIT_1状态。 - CLOSE_WAIT :服务器收到 FIN 报文段后,发送 ACK 报文段(
ACK=1, Ack=u+1),表示已收到客户端的关闭请求,进入CLOSE_WAIT状态。此时,服务器仍可向客户端发送数据。 - LAST_ACK :服务器完成数据发送后,发送 FIN 报文段(
FIN=1, Seq=w, Ack=u+1),表示服务器也准备关闭,进入LAST_ACK状态。 - TIME_WAIT :客户端收到服务器的 FIN 报文段后,发送 ACK 报文段(
ACK=1, Ack=w+1),进入TIME_WAIT状态。服务器收到此 ACK 后,进入CLOSED状态。 - CLOSED :客户端在
TIME_WAIT状态等待2MSL(最长报文段寿命)时间后,进入CLOSED状态。
(3) TCP 状态机 (TCP State Machine)
- TIME_WAIT 状态 :
- 目的1 :确保客户端发送的最后一个 ACK 报文段能够到达服务器。如果 ACK 丢失,服务器会重传 FIN 报文段,客户端在
TIME_WAIT状态可以重新发送 ACK。 - 目的2:防止"旧的"连接报文段在网络中延迟后被新的同源同目的连接接收。2MSL 的时间足以让网络中所有与该连接相关的报文段都消失。
- 目的1 :确保客户端发送的最后一个 ACK 报文段能够到达服务器。如果 ACK 丢失,服务器会重传 FIN 报文段,客户端在
IV. 流量控制与拥塞控制
1. 流量控制 (Flow Control)
- 目的:防止发送方发送数据过快,导致接收方来不及处理而丢弃数据。
- 机制 :利用 TCP 报文段中的接收窗口 (rwndrwndrwnd) 字段。接收方通过 rwndrwndrwnd 告知发送方自己当前可接收的字节数。发送方的发送窗口大小不能超过 rwndrwndrwnd。
- 实现 :发送方维护一个有效的发送窗口,其大小等于 min(rwnd,cwnd)min(rwnd, cwnd)min(rwnd,cwnd)。
2. 拥塞控制算法 (Congestion Control Algorithms)
- 目的:防止过多的数据注入到网络中,导致网络资源(路由器缓冲区)耗尽,从而降低网络的吞吐量。
- 核心变量 :
- 拥塞窗口 (cwndcwndcwnd):发送方维护的窗口,表示允许发送但尚未确认的数据量,受网络拥塞程度影响。
- 慢开始门限 (ssthreshssthreshssthresh):一个阈值,用于区分慢开始阶段和拥塞避免阶段。
- 四种算法 :
- 慢开始 (Slow Start) :
- 连接建立或发生超时重传后,将 cwndcwndcwnd 初始化为1个 MSS (Maximum Segment Size)。
- 每收到一个 ACK, cwndcwndcwnd 增加1个 MSS。
- 每个 RTT (Round Trip Time), cwndcwndcwnd 呈指数级增长。
- 当 cwndcwndcwnd 达到 ssthreshssthreshssthresh 时,进入拥塞避免阶段。
- 拥塞避免 (Congestion Avoidance) :
- 当 cwnd≥ssthreshcwnd \ge ssthreshcwnd≥ssthresh 时,进入此阶段。
- 每收到一个 ACK, cwndcwndcwnd 增加 MSS2/cwndMSS^2/cwndMSS2/cwnd (近似于每个 RTT 增加1个 MSS)。
- cwndcwndcwnd 呈线性增长。
- 当发生超时或收到3个重复 ACK 时,进入拥塞处理阶段。
- 快重传 (Fast Retransmit) :
- 当发送方收到3个重复的 ACK 报文时,不等待定时器超时,立即重传丢失的报文段。
- 这通常表明网络中可能只丢失了一个报文段,而不是发生严重拥塞。
- 快恢复 (Fast Recovery) :
- 与快重传配合使用。当发送方收到3个重复 ACK 时:
- ssthresh=cwnd/2ssthresh = cwnd / 2ssthresh=cwnd/2。
- cwnd=ssthresh+3×MSScwnd = ssthresh + 3 \times MSScwnd=ssthresh+3×MSS。
- 重传丢失的报文段。
- 每收到一个重复 ACK, cwndcwndcwnd 增加1个 MSS。
- 当收到对重传报文段的 ACK 时, cwnd=ssthreshcwnd = ssthreshcwnd=ssthresh,然后进入拥塞避免阶段。
- 注意 :快恢复避免了将 cwndcwndcwnd 降到1,从而避免了慢开始阶段,提高了网络利用率。
- 与快重传配合使用。当发送方收到3个重复 ACK 时:
- 慢开始 (Slow Start) :
V. 重点突破
A. 典型例题
1. TCP 拥塞窗口演变
Problem : 假设 TCP 的 MSS 为 1KB,初始 ssthreshssthreshssthresh 为 16KB。请以逻辑计算的方式写出 cwndcwndcwnd 随传输轮次(RTT)的变化。请设定在某个轮次发生"超时"或"收到3个重复ACK",并演示后续 cwndcwndcwnd 和 ssthreshssthreshssthresh 的变化。
Solution:
初始状态:MSS=1KBMSS = 1KBMSS=1KB, ssthresh=16KBssthresh = 16KBssthresh=16KB, cwnd=1MSS=1KBcwnd = 1MSS = 1KBcwnd=1MSS=1KB。
阶段一:慢开始 (Slow Start)
- RTT 1 :
- cwnd=1KBcwnd = 1KBcwnd=1KB。发送 1 个报文段。
- 收到 1 个 ACK。
- cwnd=1+1=2KBcwnd = 1 + 1 = 2KBcwnd=1+1=2KB。
- RTT 2 :
- cwnd=2KBcwnd = 2KBcwnd=2KB。发送 2 个报文段。
- 收到 2 个 ACK。
- cwnd=2+2=4KBcwnd = 2 + 2 = 4KBcwnd=2+2=4KB。
- RTT 3 :
- cwnd=4KBcwnd = 4KBcwnd=4KB。发送 4 个报文段。
- 收到 4 个 ACK。
- cwnd=4+4=8KBcwnd = 4 + 4 = 8KBcwnd=4+4=8KB。
- RTT 4 :
- cwnd=8KBcwnd = 8KBcwnd=8KB。发送 8 个报文段。
- 收到 8 个 ACK。
- cwnd=8+8=16KBcwnd = 8 + 8 = 16KBcwnd=8+8=16KB。
- 此时 cwnd=ssthreshcwnd = ssthreshcwnd=ssthresh,进入拥塞避免阶段。
阶段二:拥塞避免 (Congestion Avoidance)
- RTT 5 :
- cwnd=16KBcwnd = 16KBcwnd=16KB。发送 16 个报文段。
- 收到 16 个 ACK。
- cwnd=16+1=17KBcwnd = 16 + 1 = 17KBcwnd=16+1=17KB (每个 RTT 增加 1 MSS)。
- RTT 6 :
- cwnd=17KBcwnd = 17KBcwnd=17KB。发送 17 个报文段。
- 收到 17 个 ACK。
- cwnd=17+1=18KBcwnd = 17 + 1 = 18KBcwnd=17+1=18KB。
场景一:在 RTT 7 发生"超时"
- RTT 7 (发生超时) :
- cwnd=18KBcwnd = 18KBcwnd=18KB。
- 超时事件发生 :
- ssthresh=cwnd/2=18KB/2=9KBssthresh = cwnd / 2 = 18KB / 2 = 9KBssthresh=cwnd/2=18KB/2=9KB。
- cwnd=1MSS=1KBcwnd = 1MSS = 1KBcwnd=1MSS=1KB。
- 进入慢开始阶段。
- RTT 8 :
- cwnd=1KBcwnd = 1KBcwnd=1KB。发送 1 个报文段。
- 收到 1 个 ACK。
- cwnd=1+1=2KBcwnd = 1 + 1 = 2KBcwnd=1+1=2KB。
- RTT 9 :
- cwnd=2KBcwnd = 2KBcwnd=2KB。发送 2 个报文段。
- 收到 2 个 ACK。
- cwnd=2+2=4KBcwnd = 2 + 2 = 4KBcwnd=2+2=4KB。
- RTT 10 :
- cwnd=4KBcwnd = 4KBcwnd=4KB。发送 4 个报文段。
- 收到 4 个 ACK。
- cwnd=4+4=8KBcwnd = 4 + 4 = 8KBcwnd=4+4=8KB。
- RTT 11 :
- cwnd=8KBcwnd = 8KBcwnd=8KB。发送 8 个报文段。
- 收到 8 个 ACK。
- cwnd=8+1=9KBcwnd = 8 + 1 = 9KBcwnd=8+1=9KB (此时 cwndcwndcwnd 达到 ssthreshssthreshssthresh,进入拥塞避免)。
- RTT 12 :
- cwnd=9KBcwnd = 9KBcwnd=9KB。发送 9 个报文段。
- 收到 9 个 ACK。
- cwnd=9+1=10KBcwnd = 9 + 1 = 10KBcwnd=9+1=10KB。
场景二:在 RTT 7 收到"3个重复 ACK"
- RTT 7 (收到3个重复 ACK) :
- cwnd=18KBcwnd = 18KBcwnd=18KB。
- 3个重复 ACK 事件发生 :
- ssthresh=cwnd/2=18KB/2=9KBssthresh = cwnd / 2 = 18KB / 2 = 9KBssthresh=cwnd/2=18KB/2=9KB。
- cwnd=ssthresh+3×MSS=9KB+3KB=12KBcwnd = ssthresh + 3 \times MSS = 9KB + 3KB = 12KBcwnd=ssthresh+3×MSS=9KB+3KB=12KB。
- 进入快恢复阶段。
- RTT 8 (快恢复) :
- cwnd=12KBcwnd = 12KBcwnd=12KB。发送 12 个报文段 (重传丢失报文段)。
- 假设收到对重传报文段的 ACK (新 ACK)。
- cwnd=ssthresh=9KBcwnd = ssthresh = 9KBcwnd=ssthresh=9KB。
- 进入拥塞避免阶段。
- RTT 9 (拥塞避免) :
- cwnd=9KBcwnd = 9KBcwnd=9KB。发送 9 个报文段。
- 收到 9 个 ACK。
- cwnd=9+1=10KBcwnd = 9 + 1 = 10KBcwnd=9+1=10KB。
Analysis :
此例题清晰展示了 TCP 拥塞控制的四个阶段。慢开始阶段 cwndcwndcwnd 指数增长,拥塞避免阶段 cwndcwndcwnd 线性增长。关键在于区分"超时"和"3个重复 ACK"对 ssthreshssthreshssthresh 和 cwndcwndcwnd 的影响:
- 超时 :被认为是更严重的拥塞,因此 ssthreshssthreshssthresh 减半,且 cwndcwndcwnd 直接降为 1 MSS,重新进入慢开始阶段。
- 3个重复 ACK :被认为是轻微的拥塞(可能只是单个报文段丢失),因此 ssthreshssthreshssthresh 减半,但 cwndcwndcwnd 降为 ssthresh+3×MSSssthresh + 3 \times MSSssthresh+3×MSS,进入快恢复阶段,避免了 cwndcwndcwnd 降到 1,从而更快地恢复传输。
2. 序号与确认号推演
Problem: 主机 A 向主机 B 发送数据。已知主机 A 发送的第一个 TCP 报文段的序号 (Seq) 为 100,携带了 500 字节的数据。请计算主机 B 收到该报文段后,返回给主机 A 的确认号 (Ack) 和主机 A 下一个报文段的序号。
Solution:
-
主机 A 发送报文段:
- 序号 (Seq) = 100
- 数据长度 = 500 字节
- 这意味着该报文段携带的数据范围是字节 100 到字节 100+500−1=599100 + 500 - 1 = 599100+500−1=599。
-
主机 B 收到报文段:
- 主机 B 成功接收了从序号 100 开始的 500 字节数据。
- 主机 B 期望收到的下一个字节的序号是 100+500=600100 + 500 = 600100+500=600。
-
主机 B 返回确认报文段:
- 确认号 (Ack) = 600 (表示主机 B 已经收到了 600 之前的所有数据,现在期望收到从 600 开始的数据)。
-
主机 A 下一个报文段的序号:
- 主机 A 在发送完第一个报文段后,其下一个报文段的序号应该从它上一个报文段发送的数据的最后一个字节的下一个序号开始。
- 因此,主机 A 下一个报文段的序号 (Seq) = 600。
Analysis :
TCP 的序号是面向字节流的,每个字节都有一个唯一的序号。序号字段表示报文段中数据部分的第一个字节的序号。确认号字段表示发送方期望收到的下一个字节的序号,即已成功接收到的最后一个按序字节的序号加1。
B. 易错点分析
-
发送窗口的上限值 = min(rwnd,cwnd)min(rwnd, cwnd)min(rwnd,cwnd)
- 误区 :可能误认为发送窗口只受接收窗口 (rwndrwndrwnd) 或拥塞窗口 (cwndcwndcwnd) 单一限制。
- 正确理解 :发送方实际能发送的数据量(发送窗口)是受限于接收方的接收能力(流量控制,由 rwndrwndrwnd 决定)和网络当前的拥塞程度(拥塞控制,由 cwndcwndcwnd 决定)两者中较小的一个。因此,发送窗口的有效上限值是 rwndrwndrwnd 和 cwndcwndcwnd 的最小值。
-
TCP 是面向字节流的,序号增加量等于数据字节数,而不是报文段个数(SYN/FIN 消耗一个序号)
- 误区:可能认为每个报文段的序号是递增1的,或者序号只与报文段数量有关。
- 正确理解 :TCP 的序号是针对应用层数据字节的。如果一个报文段携带了 NNN 字节的数据,那么其序号会增加 NNN。
- 特殊情况 :SYN 报文段和 FIN 报文段虽然不携带应用层数据,但它们在 TCP 连接管理中具有重要意义,因此会消耗一个序号 。这意味着,如果一个 SYN 报文段的序号是 XXX,那么下一个数据报文段的序号将是 X+1X+1X+1。FIN 报文段同理。
-
区分"超时"导致 ssthreshssthreshssthresh 降为一半且 cwnd=1cwnd=1cwnd=1,与"3个重复ACK"导致 ssthreshssthreshssthresh 降为一半但 cwnd=cwnd=cwnd= 新阈值(快恢复)
- 误区:混淆两种拥塞事件发生时 TCP 拥塞控制算法的响应。
- 正确理解 :
- 超时 (Timeout) :被认为是网络发生严重拥塞的信号。TCP 会将 ssthreshssthreshssthresh 设为当前 cwndcwndcwnd 的一半,并将 cwndcwndcwnd 降为 1 MSS,强制进入慢开始阶段,以非常保守的方式探测网络容量。
- 3个重复 ACK (Three Duplicate ACKs) :被认为是网络中单个报文段丢失的信号,而不是普遍的拥塞。TCP 会将 ssthreshssthreshssthresh 设为当前 cwndcwndcwnd 的一半,但 cwndcwndcwnd 不会降为 1,而是设为 ssthresh+3×MSSssthresh + 3 \times MSSssthresh+3×MSS,进入快恢复阶段。这允许发送方在重传丢失报文段的同时,继续以相对较高的速率发送数据,提高网络利用率。