期末复习季一到,后台私信里出现频率最高的问题就是:第五章传输层到底怎么复习?刷题时每个名词都认识——端口、套接字、滑动窗口、三次握手、拥塞控制——合在一起做题又全乱了。这个问题不是你不努力,而是第五章的知识点像散装零件,缺少一条主线把它们串起来。这篇就用期末复习串讲的方式,把第五章从头到尾过一遍,说清楚每个机制解决什么问题、怎么出题、怎么避坑。适合正在期末冲刺的大学生,也适合想快速重拾传输层知识的朋友。
跟我自己当年复习的感受一样:第五章是所有章节里最容易“看了后面忘前面”的。因为 UDP 和 TCP 的每一个机制都独立看都挺简单,但凑到一张卷子里就互相打架。下面我按复习时的思维顺序来写,而不是按教材目录复制粘贴,这样你会更容易在脑子里建起一张知识地图。
1. 复习前先想清楚:第五章到底在讲哪一件事
1.1 传输层的定位:从主机到主机,变成进程到进程
很多人复习第五章,第一个动作就是背 UDP 和 TCP 的区别,背到一半开始怀疑人生。我的建议是反过来:先把第五章在整个课程里的位置搞清楚,再动手记细节。
物理层管比特,数据链路层管帧,网络层管主机到主机,到了传输层,核心任务变成进程到进程。网络层已经能把一个数据包从一台机器送到另一台机器,但一台机器上有那么多应用进程,这个包到底是给浏览器的、给邮件的、还是给文件传输的,必须由传输层回答。传输层报文段首部里那两个端口号,就是干这个用的。
从这个定位出发,第五章的主线其实只有一条:传输层如何让应用进程之间可靠、高效地通信。UDP 是“最简单直接的方式”,TCP 是“加了一堆机制来保证可靠的方式”。后面所有知识点,都是在这条主线上长出来的分支。
1.2 第五章常见的考点分布
复习之前最好先知道考什么。结合这几年期末卷子的套路,我整理了一个大致的考点热度表:
| 考点 | 常见问法 | 热度和分值 |
|---|---|---|
| 端口号、套接字、UDP特点 | 选择、填空 | 中等,基本白送 |
| TCP报文段首部字段 | 填空、选择,偶尔结合抓包 | 高 |
| 可靠传输、滑动窗口、累计确认 | 简答、分析 | 高 |
| 三次握手、四次挥手 | 简答、状态填充 | 极高 |
| 流量控制与拥塞控制 | 计算、画图、简答 | 极高 |
| 超时重传、拥塞算法变化 | 计算题 | 极高 |
这张表不需要背,但可以拿来当复习清单用。学完一遍之后对着它自查,哪一行说不清楚,就回头补哪一行。
2. 端口、套接字和UDP:先拿稳送分题
2.1 端口号:应用进程的门牌号
把应用进程想象成一栋楼里的住户,端口号就是门牌号。传输层报文段首部写清楚源端口和目的端口,数据到达主机后才能准确投递给某个进程。端口号是16位,范围 0 到 65535。
分类不用死记,重点要知道几个常见端口:HTTP 是 80,HTTPS 是 443,DNS 是 53,SSH 是 22,FTP 控制连接是 21。如果题目问“DNS 使用哪个传输层协议”,你脑子里要同时反应过来:端口 53,基于 UDP 为主,但也支持 TCP。这类关联记忆特别容易被考到。
有一个易混点要提醒:端口号标识的是进程,不是标识主机。同一个 IP 地址可以同时跑 HTTP、DNS、邮件服务,靠的就是不同端口号。如果题目说“套接字 = IP 地址:端口号”,这个公式必须刻在脑子里,因为它是一个传输层端点的完整描述。
2.2 UDP 的四句话考点
UDP 的特点用四句话就能概括:无连接、面向报文、尽最大努力交付、首部开销小。再加一句“没有拥塞控制”,基本就覆盖了几乎所有选择题。
“面向报文”怎么理解?UDP 从应用进程拿到多长的报文,就直接加一个 8 字节的首部往下传,不做拆分也不做合并。如果应用层给了一大块数据,UDP 不会帮你切成小块;反之,如果数据很小,UDP 也不会把几个小报文粘成一个。所以 UDP 报文长度是随应用报文走的。这个特性导致一个副作用:UDP 报文过长时,IP 层可能会分片,而 UDP 自己完全不管丢包和乱序。
“没有拥塞控制”听起来像缺点,但在实时应用里恰恰是优点。视频通话、游戏语音这类场景,卡一下比少一两个画面更让人难受,UDP 不搞重传、不搞等待,数据到了就播,丢了就丢,延迟自然低。DNS 查不到记录时也愿意用 UDP,因为一次请求一个包就能回来,没必要建立连接。
2.3 为什么 UDP 首部只有 8 字节
期末喜欢让你填 UDP 首部字段:源端口 2 字节,目的端口 2 字节,长度 2 字节,检验和 2 字节,一共 8 字节。这里面藏着一个“为什么”——为什么 UDP 不需要序号和确认号?
因为 UDP 没有可靠传输机制,不需要通过序号告诉对方“我发了第几个字节”,也不需要确认号告诉对方“你下一个该发哪个”。它只负责把报文从正确端口发出去,再根据目的端口找到对应进程就够了。所以首部只需要端口、长度和检验和,轻量、简单。
对比 TCP 固定首部 20 字节,UDP 少了 12 字节。这对大流量高并发场景影响很大,每个包省 12 字节,百万级请求就省出一个很可观的带宽量。这也是为什么很多高性能服务愿意在应用层自己实现“轻量可靠”逻辑,而不是直接套 TCP。
3. TCP报文段:读得懂字段,才谈得上理解机制
3.1 首部字段核心结构
TCP 可靠传输的秘密,其实都写在报文段首部里。固定首部 20 字节,核心字段如下:
| 字段 | 长度与含义 | 复习关键词 |
|---|---|---|
| 源端口/目的端口 | 各2字节,标识进程 | 门牌号 |
| 序号 seq | 4字节,本报文段数据的第一个字节的编号 | 按字节编号 |
| 确认号 ack | 4字节,期望收到对方下一个字节的序号 | 隐含“已收到” |
| 数据偏移 | 4位,指示首部长度 | 单位是4字节 |
| 标志位 | URG/ACK/PSH/RST/SYN/FIN 各1位 | 每个功能一个位 |
| 窗口 | 2字节,接收方告诉发送方还能收多少 | rwnd,流量控制 |
| 检验和 | 2字节,校验整个报文段 | 差错检测 |
| 紧急指针 | 2字节,配合 URG | 很少考,认识就行 |
有两点特别容易错。第一,“数据偏移”不是偏移量,而是首部长度。名字有迷惑性,它表示报文段从数据起点到首部末尾的距离,单位是 4 字节。20 字节固定首部对应的数据偏移值是 5。第二,序号不是从 1 开始编的,而是每一个字节都有一个编号。TCP 是面向字节流的协议,发送方把应用层数据看成连续的字节串,每个字节编一个号,报文的序号就是本报文第一个字节的编号。
3.2 序号和确认号的联动规则
这道题几乎每年都会出现,形式是给你一个 TCP 连接场景,让你填 seq 和 ack。
记一个标准规则:假设 A 发送一个报文,seq = 123,带 100 字节数据。B 收到后要回复确认,确认号 ack = 123 + 100 = 223。这个数字的含义不是“第 223 号我已经收到了”,而是“我期望你下一个字节的编号是 223”。换句话说,ack 表示接收方已经正确收到了 ack 之前的所有字节,但 223 本身还没收到。
如果 B 也想给 A 发数据,可以在同一个报文里既携带 ack 又携带 seq,这叫捎带确认。这也是 TCP 全双工的一个体现:双方都在发送数据,也都在确认对方的数据。
考试里有一类坑题:报文段不带数据,只有 ACK。这时如果 ack = u+1,它表示“你发的编号到 u 为止的我都收到了”,而确认号本身是 u+1。注意这里不存在“消费一个字节”的问题,纯 ACK 报文也占用一个序号位置,所以在三次握手时,SYN 和 FIN 各占用一个序号。
3.3 标志位怎么联想记忆
六个标志位不用死背,按功能联想:
- SYN:新建连接时用,想建立连接就亮这个灯。
- FIN:关闭连接时用,想结束连接就亮这个灯。
- ACK:确认功能,1 表示确认号有效。
- PSH:催促接收方赶紧把数据交给应用进程,别在缓冲区里等着。
- RST:连接出大问题,直接复位重置。
- URG:紧急指针有效,表示有紧急数据优先处理。
考试喜欢考“SYN 和 ACK 能不能同时为 1”,答案是可以,而且这正是第二次握手时的情况。也喜欢考“RST 出现在什么场景”,典型答案是:端口不可达或连接已经异常,接收方直接回一个 RST 让对方别再等了。
4. 可靠传输机制:ARQ、滑动窗口、累计确认
4.1 为什么需要可靠传输:IP 层是不可靠的
网络层提供的服务是“尽最大努力交付”,数据包可能在网络中丢失、重复、乱序。TCP 要在这层不可靠的网络上,给应用提供一条可靠的字节流通道。
可靠传输靠什么实现?核心是一个闭环:发送方给字节编号,接收方收到后回确认,发送方没等到确认就重传。这就是自动重传请求 ARQ 的基本思想。期末复习时,这个概念要和后面的滑动窗口放一起看。
4.2 停止等待ARQ:简单但效率太低
最早的可靠传输模型是停止等待。发送一个报文后停下来等确认,确认到了再发下一个,超时就重传。逻辑很简单,但网络利用率太低,尤其在高带宽长延时的网络里,大部分时间都浪费在“等”上。
举个例子:链路带宽 1 Gbps,往返时延 100 ms,一个报文 1 KB。发送一个包需要 8 微秒,但等待确认要等 100 毫秒。发送方的利用率不到万分之一。所以 TCP 不能这么干,必须允许连续发送多个报文,这就是滑动窗口出现的根本原因。
4.3 连续ARQ与滑动窗口:让多个报文同时在路上
滑动窗口协议允许发送方在未收到确认前,连续发送窗口内的多个报文。窗口大小决定了“在途报文”的上限。
窗口内部有发送窗口、接收窗口的概念,但期末最常考的是累计确认。累计确认的意思是:接收方不需要对每个报文都单独回确认,它只需要确认“连续收到的最后一个字节序号”。比如收到了 1、2、4、5 号段,但 3 号段丢了,这时接收方只会确认到 2 号段,并重复发送对 2 号段的确认。发送方连续收到重复确认,就会意识到 3 号段丢了。
这个机制带来两个好处:第一,确认报文数量大幅减少;第二,即使某个 ACK 丢了,后面的 ACK 也能覆盖它的作用。代价是发送方无法精确知道每个报文是否都到达,如果中间丢了一个,就不知道后面哪些是被缓存、哪些被丢弃。由此演化出两个处理策略:回退N帧 GBN和选择重传 SR。
GBN 的处理方式是,一旦发现缺了第 N 个报文,发送方就重传 N 及其之后的所有报文。实现简单,但浪费带宽,因为很多已经正确到达的报文也要被重传。
SR 的处理方式是,接收方把乱序到达的报文先缓存起来,发送方只重传真正丢失的那几个。效率高,但接收方需要额外缓存空间,协议也更复杂。
期末选择题特别喜欢问“如果只是偶尔丢包,选哪个”“如果链路质量差经常丢包,选哪个”。前者用 GBN 实现简单、开销可控;后者用 SR 才能避免大量无效重传。而 TCP 在实际实现中,综合了累计确认和选择重传的思路,对乱序数据有一定的缓存能力,但考试默认按经典模型来理解即可。
4.4 超时重传时间的直觉
RTO 应该设置多大?太短,很可能报文没丢,只是延迟稍大,就会触发多余重传;太长,真的丢了也迟迟不重传,用户体验差。所以 RTO 要动态跟 RTT 走,常用算法是用平滑后的平均往返时延 RTTs 加上 4 倍偏差,得到一个略大于平均值的门限。
期末不太要求背公式细节,但你要能说清楚一句话:RTO 应该是动态变化的,不能设为固定值。如果题目问“RTO 太大或太小会有什么后果”,就按上面两句话回答,足够拿分。
5. TCP连接管理:三次握手和四次挥手,别只会背状态
5.1 三次握手:建立连接的最小成本方案
TCP 建立连接需要三次握手,交换三个报文。假设客户端叫 A,服务端叫 B:
- A 发送 SYN=1,初始序号 seq = x,进入SYN_SENT状态。
- B 回复 SYN=1,ACK=1,seq = y,ack = x+1,进入SYN_RCVD状态。
- A 再回复 ACK=1,seq = x+1,ack = y+1,进入ESTABLISHED状态。B 收到这个 ACK 后也进入ESTABLISHED状态。
为什么一定要第三次握手?最经典的答案是防止已失效的连接请求突然到达服务端。假设 A 第一次请求在网络中滞留了很久,A 超时后重新发了一次请求,顺利完成数据传输并关闭连接。这时那个滞留的旧请求突然到达 B,如果只有两次握手,B 会认为 A 又要建立新连接,于是分配资源、进入连接状态,但 A 根本不会发数据,这条连接就是纯浪费。三次握手让 B 必须等到 A 的第三次确认,否则不会正式建立连接。
还有一个小问题容易被考:为什么 SYN 报文要消耗一个序号?因为 SYN 本身是一个虚拟字节,握手时需要让双方的序号保持同步。同理,FIN 也要消耗一个序号,否则关闭连接时的确认号对不上。
5.2 半连接与SYN洪泛:握手也能被攻击利用
服务端收到 SYN 后进入 SYN_RCVD,把连接挂到半连接队列,等待客户端的第三次握手。这个设计本身是为了防止无效连接占资源,但也带来一个安全隐患:攻击者大量发送只有 SYN 的报文,却不完成第三次握手,服务端的半连接队列很快被占满,正常的客户端请求就进不来了。
这就是教材里常说的SYN 洪泛攻击。复习到这里,理解“半连接队列”比背攻击名更重要。因为考试往往不会直接考攻击本身,而是给你一张状态表,问“服务端在哪两个状态之间的资源开销最大”之类的问题。
5.3 四次挥手:全双工的优雅退出
TCP 是全双工通信,数据可以同时在两个方向上传送。因此关闭连接时,每个方向都要单独关闭,这就是为什么需要四次挥手:
- A 发送 FIN=1,seq = u,进入FIN_WAIT_1。
- B 回复 ACK=1,ack = u+1,进入CLOSE_WAIT。A 收到后进入FIN_WAIT_2。
- B 的数据发送完毕,发送 FIN=1,seq = w,进入LAST_ACK。
- A 回复 ACK=1,ack = w+1,进入TIME_WAIT。B 收到后进入CLOSED。A 再等 2MSL 后关闭。
为什么是四次而不是三次?因为 B 收到 FIN 时,可能还有数据没发完。它不能立刻关闭发送方向,所以先回一个 ACK,告诉 A“我知道你要关了,但我这边还没完”。等 B 的数据发完,再发自己的 FIN。这个拆开的过程就多出了一次交互。
TIME_WAIT 的 2MSL 也是高频考点。两个作用:一是确保最后一个 ACK 能到达 B,如果 ACK 丢失,B 会重发 FIN,A 要能再次响应;二是让本次连接中残留的旧报文在网络中消失,避免混入新建连接。MSL 是报文最大存活时间,2MSL 可以保证一个方向上的报文和它的确认都从网络中自然消失。
期末复习时,建议把两端的状态变化画在一张表里,自己填一遍。画完三次握手和四次挥手,状态管理题基本就能拿下了。
6. 流量控制与拥塞控制:最容易混淆的一对
6.1 先分清两个“控制”的立场
流量控制解决的是接收方处理不过来的问题,拥塞控制解决的是网络中间设备处理不过来的问题。一个是端到端之间的事,一个是整个网络负载的事。
逻辑上,发送方的发送窗口最终要同时受两个因素限制:接收方的接收能力 rwnd 和网络当前能承载的能力 cwnd。期末常考一句话:实际发送窗口 = min(rwnd, cwnd)。rwnd 来自 TCP 首部的窗口字段,由接收方在确认报文里告诉发送方;cwnd 是发送方根据丢包和时延自己估算出来的。
6.2 流量控制:用接收窗口踩刹车
流量控制实现起来很直接:接收方告诉发送方“我的缓冲区现在还能收 N 字节”,发送方就只发 N 字节。N 就是这个报文里的窗口字段 rwnd。
有一个经典问题:如果接收方窗口变为 0,发送方就停下来,但万一接收方之后恢复了、发来一个“窗口已更新”的通知,这个通知丢了怎么办?发送方会一直等,形成死锁。解决方法是持续计时器:发送方隔一段时间主动发一个 1 字节的探测报文,迫使接收方重新回复当前窗口大小。
6.3 拥塞控制的四个算法:慢开始、拥塞避免、快重传、快恢复
拥塞控制的核心思想是:发送方不能一上来就猛发,要一点点试探网络的承载能力。TCP 用拥塞窗口 cwnd 来衡量这个能力。
慢开始:cwnd 从 1 开始,每收到一轮确认,cwnd 翻倍。1、2、4、8、16……呈指数增长。注意“慢开始”的“慢”只是起点低,增长速度其实很快。
拥塞避免:当 cwnd 达到慢开始门限 ssthresh 后,改为每个往返时间 RTT 只增加 1 个 MSS,变成线性增长,用来避免快速增长触发网络拥塞。
超时处理:一旦发生超时,说明网络可能已经堵了。TCP 会把 ssthresh 设为当前 cwnd 的一半,然后把 cwnd 重置为 1,重新走慢开始。
快重传:超时等待往往太久,所以 TCP 增加了快重传。发送方如果收到 3 个重复 ACK,说明某个报文段丢了,不等超时立即重传。
快恢复:配合快重传,发生快重传时网络可能只是轻微拥塞,不用退回 1。TCP 会将 ssthresh 设为 cwnd 的一半,cwnd 也设为这个值,直接进入拥塞避免阶段,而不是重新慢开始。
这四个算法经常一起出现在计算题里,核心数字规律其实就一条:出现超时,cwnd 归 1、重走慢开始;出现 3 个重复 ACK,cwnd 砍半、进入快恢复。
6.4 一个典型的拥塞窗口计算套路
题目一般会给一个初始 ssthresh,然后让你填 cwnd 的变化。比如:
假设初始 ssthresh = 16,当前 cwnd = 1。慢开始阶段:1、2、4、8、16。到达 16 后进入拥塞避免:17、18、19……如果 cwnd 涨到 20 时发生超时,则执行:ssthresh = 10,cwnd = 1,重新慢开始。之后 cwnd 依次为 1、2、4、8、10(到达门限),再进入拥塞避免继续 11、12……
做题时注意两个细节:第一,题目问的“第几个 RTT 后 cwnd 是多少”要把慢开始指数增长算对;第二,注意“收到 3 个重复 ACK”和“超时”是两种不同分支,千万别搞混。
流量控制与拥塞控制对比表,考前可以再扫一眼:
| 对比项 | 流量控制 | 拥塞控制 |
|---|---|---|
| 目标 | 不让接收方缓冲区溢出 | 不让网络过载 |
| 控制主体 | 接收方通过 rwnd 限制发送方 | 发送方根据网络反馈调节 cwnd |
| 实现机制 | 滑动窗口、窗口通告 | 慢开始、拥塞避免、快重传、快恢复 |
| 是否端到端 | 是 | 是,但体现的是网络整体负载 |
7. 期末考场上,这套题可以这样下手
7.1 先做概念送分题,再做计算题
传输层的卷子普遍不大,但时间容易浪费在犹豫上。我的建议是:拿到卷子先扫一遍,凡是端口号、UDP 特点、TCP 首部字段这类题,立刻做掉,因为它们几乎没有计算量,也不需要画图。这部分分数稳定,先拿到手能稳定心态。
三次握手和四次挥手的题,如果考状态填充,就按“客户端状态 → 服务端状态 → 标志位”的顺序推。例如看到 SYN_SENT,马上反应这是客户端发完 SYN 后进入的状态,对方应该回 SYN+ACK 并进入 SYN_RCVD。状态机不用背得滚瓜烂熟,但每个状态前面是谁发什么报文、后面会收到什么报文,一定要能推出来。
拥塞控制计算题,建议先在草稿纸上写出两条分支公式:
- 超时:ssthresh = cwnd / 2,cwnd = 1,进入慢开始。
- 3 个重复 ACK:ssthresh = cwnd / 2,cwnd = ssthresh,进入拥塞避免。
把分支写在草稿纸上再代入数字,出错率会低很多。
7.2 必背清单和常见坑
最后一周如果时间不够,优先背以下几条:
- UDP 首部 8 字节,TCP 固定首部 20 字节。
- TCP 序号是字节编号,确认号表示“期望下一个字节”,本质是累积确认。
- SYN 和 FIN 各占一个序号。
- 三次握手防止“已失效的连接请求突然到达”。
- TIME_WAIT 等待 2MSL 的原因:保证最后一个 ACK 到达、让旧报文消失。
- 发送窗口 = min(rwnd, cwnd)。
- 流量控制由接收方驱动,拥塞控制由发送方根据网络状况驱动。
常见坑也集中在这几条:数据偏移单位是 4 字节,不是字节;快恢复不是回到 1;纯 ACK 不携带数据但仍要占用一个序号位置;累计确认不是等到接收方明确回“我全部收到了”才有效,而是确认号之前的所有字节都视为正确到达。
7.3 冲刺阶段个人习惯分享
我自己复习第五章时有个习惯:把 TCP 的十六个状态写在小卡片上,然后随机抽两个状态,逼自己说出“从 A 到 B 发生了什么”。第一次做可能卡壳,做几轮之后,连接管理的整个流程就刻进肌肉记忆了。
另一个习惯是自制对比表。不用买现成的,自己拿一张 A4 纸,左边写 UDP,右边写 TCP,尽量不看书默写,包括首部字段、拥塞控制算法、适用场景。默写完再和课本对一遍,勾出漏掉的内容。这个过程比单纯背表格有用得多,因为你会被迫回忆那些藏在角落里的细节。
最后再分享一个小技巧:刷题时不要只看正确选项,务必把错误选项为什么错也写出来。比如选择题说“TCP 支持广播”,你就要顺手在空白处写“TCP 只支持点对点,广播只能由无连接的 UDP 在特定场景实现”。这样一题顶三题,最后几天效率会高很多。第五章的复习说难不难,说简单也不简单,关键就在把机制背后的“为什么”吃透。祝你期末顺利。