Stanford CS144 学习笔记 (二):传输层与数据通信机制

在这里插入图片描述

导语:本单元着重讲解传输层。主要目的是了解网络通讯中面临的数据传输问题,以及 TCP 和 UDP 等协议是如何在不可靠的网络层之上,构建出满足应用需求的传输服务的。

Main Topics

  • 三种广泛使用的协议
    • TCP:应用间字节流的可靠传输。
    • UDP:应用间数据报的不可靠传输。
    • ICMP:检测网络何时出问题。
  • TCP 的工作原理:滑动窗口 (Sliding Window)、Go-back-N、Selective repeat、TCP 状态机。
  • 端到端原则 (End to End):网络架构的核心哲学。
  • 错误检测方法:3 种保障数据安全与完整性的机制。

1. The TCP Service Model (TCP 服务模型)

TCP (Transmission Control Protocol) 为应用程序提供了按顺序的、可靠的、端到端的字节流交付服务

1.1 Transmission Control Protocol (TCP)

  • 对等通信 (Peer communication):TCP 在通信双方的传输层之间建立对等连接。
  • 三次握手 (3-Way Handshake):TCP 的通讯必须通过三次握手来建立可靠连接:
    1. SYN:A 向 B 发送同步信号,并携带一个起始序列编号 (ISN)。
    2. SYN + ACK:B 收到后,返回一个同步信号 (携带 B 自己的起始编号),并确认 (ACK) 接收到了 A 的请求。
    3. ACK:A 发送 ACK,确认接收到了 B 的反向通讯请求,连接正式建立。

1.2 TCP 字节流服务 (Byte Stream Service)

  • 字节流是一个连续的字节时间序列。TCP 将应用程序需要发送的常见数据统统看作“字节流”。
  • 在网络传输时,TCP 会将连续的流 (Stream) 分割为一个个独立的段 (Segment)
  • 如果发送的某个段在规定时间内没有收到接收方的回应 (ACK),TCP 会选择简单粗暴的策略:重发

1.3 Connection teardown (连接拆除)

连接的关闭同样需要经过严谨的握手确认过程:

  1. FIN:A 发送 Finish 报文,表示 A 已经没有数据要发送了。
  2. ACK (+ Data):B 收到后回应 ACK。此时 B 可能还有没发完的数据,所以可以继续发送新数据,连接处于“半关闭”状态。
  3. FIN:等 B 也发送完毕后,B 发送 Finish 报文。
  4. ACK:A 发送 ACK,确认 B 的关闭请求,连接最终安全关闭。

1.4 Model 表现 (模型特性)

TCP 究竟提供了一个什么样的传输服务?

  • 可靠传输:利用 ACK 表示确认接收。
  • 错误校验:利用 Checksums (校验和) 检测数据是否损坏。
  • 序列号 (Sequence):利用序列号(一开始发送的起始编号)进行数据排序和丢包检测。
  • 流量控制 (Flow Control):防止双方过载。如果 A 发送过快而 B 处理不过来,TCP 会动态调整,确保双方都在可承受范围内发送数据。
  • 拥塞控制 (Congestion Control):感知整个网络的拥堵情况,避免网络崩溃。

1.5 TCP Segment Format (TCP 数据段格式)

TCP 数据段会被封装在 IP 数据包内,体现了网络分层的封装原则
| IP Hdr | TCP Hdr | TCP Data |
TCP Header (头部) 包含以下核心字段:

  • Source port / Destination port:源端口与目标端口(标识具体的应用程序进程)。
  • Sequence:序列号。
  • Ack Sequence:确认号。
  • Checksum:校验和。
  • Window size:窗口大小(用于流量控制)。
  • Urgent pointer:紧急指针标识。
  • (TCP Options):其他附加选项(如最大段大小 MSS)。

1.6 TCP Unique ID (唯一标识)

主机 A 会使用递增的随机端口来标识新的连接。TCP 会挑选一个随机的初始序列号 (ISN, Initial Sequence Number) 来避免和历史遗留的旧连接 ID 或序列号混淆。

1.7 Sequence Numbers (序列号)

序列号告诉主机当前数据段在整个字节流中的起始值(即下一次传输的偏移量)。通过对比期望的序列号和实际收到的序列号,接收方能进行初步的丢包和乱序校验。

1.8 TCP Sliding Window (滑动窗口)

为了提升传输效率,TCP 采用了滑动窗口技术(在第 8 节中会有详细讲解)。


2. The UDP Service Model (UDP 服务模型)

UDP (User Datagram Protocol,用户数据报协议) 是提供给那些不需要严格可靠性保证的应用使用的协议。

2.1 UDP Datagram Format (UDP 数据报格式)

UDP 的头部极其精简,只有短短 8 个字节:

  • Source portDestination port
  • Length:至少为 8 字节(即 UDP 头部的最小长度)。
  • Checksum (optional):校验和是可选的,如果使用,会覆盖部分 UDP 数据头来进行完整性校验。

2.2 UDP: Port Demultiplexing (端口多路分解)

UDP 可以看作是一个多路分解协议:它仅仅是将接收到的 IP 数据包,根据目标端口号 (Port) 分发给对应的应用程序。

2.3 UDP 表现 (特性与应用)

  • 特性:无连接建立 (无需握手),Packets 可能会以任何顺序到达(但应用层可以自己在包里加序列号来重新排序)。
  • Unreliable delivery (不可靠交付):没有 ACK,没有丢包检测机制 (无 Window size 和 Sequence),也没有流量控制 (Flow control)。
  • 为什么还要用 UDP? 因为它极度轻量、快速,开销极小。非常适合提供简单的 Request-Response 基础服务,或者对实时性要求极高、能容忍偶尔丢包的场景。
  • 经典应用DNS (Domain Name System, 域名系统) 查询。

3. The ICMP Service Model (ICMP 服务模型)

ICMP (Internet Control Message Protocol,互联网控制消息协议) 用于报告网络错误和诊断问题。虽然它被封装在 IP 数据包中(看似在传输层之上),但它本质上是为网络层服务的。

3.1 网络层的工作职责

  • IP 协议:负责将 IP 数据包逐跳传输。路由器利用特定的路由算法生成路由表,并据此填充转发表来进行数据转发。
  • ICMP 协议:作为 IP 的副手,负责帮助 Host 和 Router 之间交流,报告错误 (Error),以及找出出问题的数据包路径。

3.2 ICMP run above the Network Layer

在网络连接出现问题时,ICMP 发挥关键作用。

  • EXAMPLE: 目标不可达 (Destination Network Unreachable):如果数据包到达某个路由器,但目标地址在该路由器的转发表中不存在,路由器就会丢弃该包,并向上游发送一个 ICMP 报错信息。

3.3 ICMP 表现

  • Reporting Message:自带报错的类型和代码信息。
  • Unreliable:ICMP 自身也是简单的、不可靠的数据报服务。如果不幸 ICMP 报错包也丢了,它不会重试 (no retries)

3.4 ICMP Message Type (消息类型)

不需要死记硬背,用到时查阅 Internet RFC 792 即可。常见类型:

  • Type 0 - Code 0:Echo Reply (回显应答)。
  • Type 3 - Code 0:Destination Network Unreachable (目标网络不可达)。
  • Type 11 - Code 0:TTL Expired (生存时间超时)。

3.5 How “ping” uses ICMP (Ping 工具原理)

ping 命令用来检查本机与目标主机是否有网络连接。它不涉及 TCP/UDP,而是直接调用 ICMP,发送一个 ICMP Echo Request (回显请求),目标主机收到后返回 Echo Reply

3.6 How “traceroute” uses ICMP (Traceroute 工具原理)

traceroute 告诉我们数据包跳跃经过的具体路径节点。

  • 实现原理:通过不断发送 TTL(生存时间,表示最多经过几跳)递增的 UDP 数据包(TTL=1, 2, 3…)。
  • 当数据包到达第一跳路由器时,TTL 减为 0,路由器丢弃该包并返回一个 ICMP 11 (TTL Expired) 报错。traceroute 捕获这个报错,就知道了第一跳路由器的 IP 地址。依次类推,直到到达最终目标。

4. The End-to-End Principle (端到端原则)

这是互联网设计中最核心的哲学:强调“正确性”的强端到端原则

4.1 Application View of the World (应用的世界观)

应用程序进行网络通信非常简单,只需调用基础的 Socket (套接字) 即可完成。网络底层默默提供了很多帮助:数据压缩、格式化、甚至硬件级的安全加密和移动性支持。
但是,为什么底层网络不包揽一切(比如保证数据绝对不错不丢)?
因为网络只能提供“帮助”,而不能保证业务逻辑的最终“正确性”。真正的正确性,必须依靠终端(端到端)自己来校验。

4.2 Example: File Transfer (文件传输例子)

在文件传输时,每一跳的路由器虽然都有错误检测 (Error detection),但这只检测了线路传输过程中的错误,而检测不到内存存储中的错误(比如路由器内存坏了导致比特反转)。
因此,确保文件正确无误送达的唯一方式,是在接收端对整个文件进行校验(即端到端原则):网络可以帮忙优化,但绝不能完全保证正确。

4.3 Example: Link Reliability (链路可靠性)

链路层提供的帮助极大提升了性能:

  • 有线链路:非常可靠,包正确发送率达 99.99%。
  • 无线链路:极易受干扰,原生包正确率仅 50~80%。
    链路层可以在中间层通过物理重传等优化手段,将无线链路的成功率提升到 99%。底层优化是有价值的,但依然无法避免极端情况下的失效。

4.4 “Strong” End to End (强端到端)

复杂的逻辑不应在网络中间层实现,只应在网络边缘(计算机终端)执行。

  • 强调网络的简洁性。如果在中间路由器做太多特定业务优化,不仅不一定总是正确,还会导致网络僵化 (Network Ossification),使得未来的底层网络难以升级和改变。

5. Error Detection: 3 schemes (错误检测的三种方案)

网络中的数据包需要添加冗余位来识别错误,主要有三种常见机制。我们需要了解其差异,从而在系统设计时做出正确的协议决策。

5.1 Error Detection (错误检测概览)

通过在数据的头部或尾部加入校验码。常见的如 Checksum、CRC、TLS MAC。

5.2 Checksum (校验和)

  • 特点:快速 (fast) 且计算成本低 (cheap),但鲁棒性较差 (not very robust,较脆弱)。
  • 实现:IP / UDP / TCP 使用的是 16位反码求和 (one’s complement checksum algorithm)。对比特位进行简单累加运算作为数据包的校验和。

5.3 Cyclic redundancy code (循环冗余校验码, CRC)

  • 特点:计算成本高于 Checksum,但鲁棒性极好,能检测更多复杂的连续错误。如今在硬件(特别是链路层 Link Layer)中极易实现。
  • 主要思想:将 nnn bits 的数据经过多项式除法,提取为 ccc bits 的特征码(其中 c≪nc \ll ncn)。
  • 极小概率出现碰撞(两个不同的包算出同样的 CRC,概率为 2−c2^{-c}2c)。

5.4 Message authentication code (消息认证码, MAC)

  • 特点:强大的密码学原理,只有拥有秘密信息(密钥)的人才能生成和查看信息。对“恶意篡改”具有极强的抵抗力。
  • 注意:千万不要与网络硬件的 MAC 地址 (Media Access Control) 混淆!如果你更改了信息的任何一个 bit,将导致整个特征码雪崩式改变。不过,它主要用于防篡改,用于常规通信噪音的“错误检测能力”不如 CRC 高效。

5.5 Quiz (检测能力小结)

  • 8/16位 Checksum:能检测 1 bit 错误;但不能必然检测 2 bit 错误、9 bit 错误,或者相隔很远(比如 100 bits)的抵消错误。
  • 8/16位 CRC:能完美检测 1 bit、连续的突发错误;8 bits CRC 无法检测某些 2 bit 错误,但 16 bits 可以。不过它们都无法保证检测出相隔很远的随机错误。
  • 32位 MAC:它的设计目的不是为了常规的信道纠错,所以单从纠正信道噪音的角度看,“不能保证检测到特定的物理噪音错误”,它只保证数据的不可伪造性。

6. Finite State Machines (有限状态机, FSM)

网络协议的运转逻辑极其复杂,因此引入有限状态机 (FSM) 进行建模。系统由有限的“状态 (State)”组成,状态之间的“边”定义了触发的“事件 (Event)”和采取的“行动 (Action)”。系统同一时刻必定且只能处于一种确定状态。

6.1 FSM Example: HTTP Request

一个简单的 HTTP 请求事件会导致系统进入不同的状态。

  • 例如,发起请求后等待响应,根据不同的响应结果切换到结束状态或错误状态。
  • 协议设计者必须考虑极其严谨的具体情况:如何处理空闲状态的特殊请求?如何处理 Close Connection?如果出现了未定义状态或非法操作该怎么办?

6.2 FSM Example: TCP Connection

TCP 连接的完整生命周期就是一个典型的复杂有限状态机,状态转移类似于数字电路中的状态转移图。
(注:这里梳理了三次握手与四次挥手背后的理论模型,也是本单元最需要花时间手动画图推演的部分,具体状态机详解见第 11 节。)


7. Flow Control - Stop and Wait (流量控制:停等协议)

当通信双方的收发数据能力不对等时,流量控制 (Flow Control) 是实现高效通信的重要因素。

  • 核心目标:发送方的发送速度绝对不能超过接收方的处理能力
  • 机制:接收方必须给发送方提供显性(ACK 确认)或隐性(超时)的反馈。

7.1 Stop and Wait (停等协议)

  • 基本算法:发送方发送一个包,然后停下来,死死等待接收方发来 ACK 确认后,才会发送下一个数据包。如果长时间没有回复,就超时重发。
  • 致命问题:如果网络出现延迟,发送方超时重发了 Data,接收方收到了两份 Data,如何区分这是新数据还是旧数据?
  • 解决方案:引入 1 bit 的计数器 (cnt = 0 或 1)。标记 Data 0 对应 ACK 0Data 1 对应 ACK 1,交替进行。但这依然无法解决网络链路极长时,效率极其低下的问题。

8. Flow Control - Slip Window (流量控制:滑动窗口)

前情提要:Stop and Wait (SaW) 算法效率低下,因为它无法充分利用网络容量。
网络传输存在两个物理限制:

  • Bottleneck (传输瓶颈):如 10 Mbps,代表接收方每秒的最大接收数据量。
  • RTT (往返时间):数据跑个来回需要的时间。
    滑动窗口技术通过允许发送方并发发送多个数据包来填满网络管道。

8.1 Sliding Window Sender (发送端窗口)

每一段数据都有一个序列号 (SeqNo)。发送方维护着三个核心变量:

  • SWS (Send Window Size):发送窗口大小(允许同时在路上跑的最多包数量)。
  • LAR (Last Acknowledgment Received):接收方最后一次确认的位置编号。
  • LSS (Last Segment Sent):发送方最后一个发出的段的位置编号。
    发送方必须严格维护一个不等式:LSS−LAR≤SWSLSS - LAR \le SWSLSSLARSWS(即:最后一个发送 - 最后一个接收确认 ≤\le 窗口大小)。只有当收到新的 ACK 更新 LAR 时,窗口才能向前滑动。

8.2 Example (接收端示例)

  • RWS (Receive Window Size):接收方缓存的大小,只要在这个窗口内的包,接收方都可以先收下缓存。
  • 累计确认 (Cumulative Acknowledgment):注意,TCP 不是收到第 nnn 个包就确认第 nnn 个包。TCP 发送 ACK n,意思是:“我已经完美接收了序列号 n−1n-1n1 及之前的所有数据,现在期待收到 nnn。”
  • 如果中间丢了包,接收方会连续发送相同的最后接收数据 ACK(冗余 ACK),来隐式提醒发送方丢包了。

9. Retransmission Strategies (重传策略)

当滑动窗口中某个包丢失时,传输协议需要根据 SWS 和 RWS 的大小等因素,小心地选择重传策略。

9.1 Go-Back-N (回退 N 步重传)

  • Pessimistic behavior (悲观策略):如果序列号为 nnn 的数据包丢失,即使接收方已经完美收到了 n+1,n+2n+1, n+2n+1,n+2,接收方也会将其全部丢弃。
  • 发送方一旦发现 nnn 丢失,会停止发送新数据,回退到 nnn,并把 nnn 和之后的所有包全部重传一遍,就像事件倒流一样。
  • 这种策略通常在接收方窗口大小 (RWS) 为 1 的简单设备上使用。

9.2 Selective Repeat (选择性重传)

  • 乐观策略:只精确重新传那个没有收到 ACK 的特定的包。接收方如果收到乱序的包,会将其暂时存在 RWS 缓存中,等缺失的那个包重传到了,再按顺序拼装上交。
  • 缺点:如果有大量连续数据包丢失,选择性重传逐个挑着重发的效率,实际上比 Go-Back-N 的整批重发还要慢。

10. TCP Header (TCP 头部详解)

TCP 头部标准长度为 20 字节(即 5 行 32 bits / 4 octets),包含极其丰富的信息控制字段:

  • Source port / Destination port
  • Sequence number:当前数据段的字节偏移量。
  • Acknowledgment number:期望收到对方下一个段的序列号。
  • Offset:数据偏移,告诉你 TCP 报头有多长(因为 Options 是可变长的)。
  • Reserved:保留位。
  • 核心控制位 (Flags)
    • U (Urgent bit): 与下方的 Urgent pointer 配合,指向紧急数据。
    • A (Ack bit): 确认号是否有效(除了第一次建立连接的 SYN,后续所有的包 A 位都是 1)。
    • P (Push bit): 提示接收方尽快把数据推送给应用层。
    • R (Reset): 发生了严重错误,强制重置连接。
    • S (SYN): 建立连接时使用,需要告诉对方初始序列号。
    • F (FIN): 数据发送完毕,请求拆除链接。
  • Window:告诉对方自己的接收窗口还剩多少空间(用于流量控制)。
  • Checksum:校验和。
  • Urgent pointer / Options / Padding

10.1 安全性

为什么三次握手时不固定从序列号 0 开始,而是使用随机的 ISN?
因为如果每次序列号规则固定,恶意攻击者很容易猜测出你的序列号,然后伪造 IP 源地址,将含有恶意代码的数据包注入到你的 TCP 连接中。随机 ISN 大大降低了这种盲打注入的风险。


11. TCP Setup and Teardown (TCP 建立与拆除详解)

结合 TCP 头部的 Flags,进一步剖析 TCP 状态机中的握手细节。

11.1 3-way Handshake (三次握手)

  • 建立连接,发送方是 Active (主动) 的,接收方(服务器)是 Passive (被动) 的。
  • 双方必须知道对方监听的端口号。
  • 过程:发送 SYN -> 对方响应 SYN + ACK -> 本机确认 ACK。这三步不仅确认了双向通信通畅,还互相交换了随机化的起始序列号。

11.2 Simultaneous open (同时打开现象)

如果通信双方极为巧合地同时向对方发起主动连接(都是 Active),双方都会先发送 SYN,接收后都会回复 SYN+ACK。此时连接建立过程会演变成罕见的**“四次握手”**,但连接依然可以正常建立。

11.3 Connection Teardown (连接拆除:四次挥手)

因为 TCP 是全双工的,Both sides must send FIN to terminate a connection(双方都必须独立发送 FIN 来终止自己方向的连接)。

  • A -> B: 发送 FIN (seq SA), 附带 ACK SB
  • B -> A: 收到后确认,发送 ACK SA+1
  • (B 继续发完自己剩下的数据)
  • B -> A: 发送 FIN (seq SB), 附带 ACK SA+1
  • A -> B: 收到后确认,发送 ACK SB+1
  • (确认序列号 (seq) 的方式,一般是对方的期望 Ack = 当前 Seq + 1;确认 FIN 的方式也是发送对该 FIN 的 ACK,双方甚至可以并行发送 FIN)。

11.4 Cleaning Up Safely (安全地清理连接)

A (主动关闭方) 在发送了最后一个 ACK 之后,绝对不能马上销毁连接并释放资源

  • 问题:如果这最后一个 ACK 丢了怎么办?B 迟迟收不到确认,就会疯狂重发最后一个 FIN。如果 A 已经销毁了连接,就会回应 RST 错误包。
  • 解决:主动关闭者必须进入一个 TIME_WAIT 状态,等待 2MSL (Maximum Segment Lifetime,最大的段寿命的两倍时间)。这确保了网络中所有残留的延迟包都死干净,也确保了 B 能收到最后的 ACK(如果丢了,在这个时间内还能响应 B 重发的 FIN)。

11.5 三次握手 关闭连接

如果 B 收到 A 的 FIN 时,自己刚好也没有数据要发了,B 可以把自己的 FIN 捎带在 ACK 一起发过去,此时四次挥手就可以被优化压缩为三次挥手

  1. 发送 FIN0
  2. 确认 FIN0 并发送自己的 FIN1 (合并发送)。
  3. 确认 FIN1

11.6 Full TCP FSM (完整的 TCP 有限状态机)

整合上述的所有过程,就构成了计算机网络中最经典的 12 种状态图谱:

  • 建连阶段LISTEN -> SYN_SENT / SYN_RCVD -> ESTABLISHED
  • 断连阶段 (主动)FIN_WAIT_1 -> FIN_WAIT_2 -> TIME_WAIT -> CLOSED
  • 断连阶段 (被动)CLOSE_WAIT -> LAST_ACK -> CLOSED
    自己拿纸笔推演并画一次这个有 12 个状态的转移图,是彻底掌握 TCP 最好的练习!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值