TCP“报文段”和 UDP“用户数据报”
本文最后更新于3 天前,其中的信息可能已经过时,如有错误请发送邮件到184874483@qq.com

一、先把最容易混的地方捋顺:TCP“报文段”和 UDP“用户数据报”到底有什么区别

这部分在考研里很容易被一句“TCP 面向连接、UDP 无连接”带过去,但真正做题时,往往考的是更细的报文、字段、边界和机制差异。

先说一个很关键的表述:传输层里,UDP 的 PDU 通常叫“UDP 用户数据报”,TCP 的 PDU 通常叫“TCP 报文段”。再往下封装到网络层,统一都会变成 IP 数据报。也就是说,严格来说,常说的“TCP 数据包”和“UDP 数据包”只是口语化说法,考试里更规范的叫法还是“TCP 报文段”“UDP 用户数据报”。

二者最核心的差别,不只是“是否可靠”,而是“传输对象的组织方式”不同。

UDP 面向报文。应用层交给 UDP 一条报文,UDP 通常就按这一条报文来发送,接收方一次也按一个完整报文来交付。也就是说,UDP 保留应用层报文边界。发 3 次,就对应 3 个独立的 UDP 用户数据报;接收方不会把两次发送自动拼起来,也不会把一次发送自动拆成多次交付给应用层。

TCP 面向字节流。应用层看到的是连续字节序列,而不是一条一条独立消息。应用层即使分两次 write,也可能被 TCP 合并到一个报文段里发送;也可能一次 write 很大,被 TCP 拆成多个报文段发送。接收方拿到的也是连续字节流,因此 TCP 不保留应用层消息边界。这是 TCP 和 UDP 在“报文”层面最大的本质区别,也是考试里特别爱混淆的一点。

从首部看,UDP 首部很短,只有 8B,字段也少:源端口、目的端口、长度、检验和。它有长度字段,所以 UDP 用户数据报的总长度可以直接在 UDP 首部里看到。

TCP 首部最小 20B,可变长,因为可以带选项。它的字段明显更多:源端口、目的端口、序号、确认号、数据偏移、标志位、窗口、校验和、紧急指针,以及若干选项。也正因为 TCP 要实现可靠传输、流量控制、拥塞控制,所以它的首部远比 UDP 复杂。

可以把二者先记成这样:

对比项UDPTCP
连接方式无连接面向连接
可靠性不保证可靠可靠传输
传输对象面向报文面向字节流
是否保留消息边界保留不保留
首部长度8B最小 20B,可变
是否有序不保证保证按序交付
流量控制
拥塞控制
典型单位UDP 用户数据报TCP 报文段

考试里还有一个常见陷阱:UDP 的“长度”是 UDP 首部字段之一;TCP 首部里没有专门的“总长度字段”,TCP 报文段长度要结合 IP 层长度来推。


二、TCP 报文段首部中最常考的标志字段有哪些

考研里最常考的是 6 个经典标志位,也就是:

URG、ACK、PSH、RST、SYN、FIN

现在很多资料还会看到 ECE、CWR,那是与 ECN 相关的扩展标志位。若是 408 风格或常规考研题,默认先把前面 6 个吃透,已经足够应对绝大多数题。

1. SYN:建立连接

SYN = Synchronize Sequence Numbers,用于建立连接时同步序号。

它最典型地出现在三次握手里。只要看到 SYN,基本就要联想到“连接建立”。并且要记住一个极其重要的规则:

SYN 会消耗一个序号。

这句话后面做三次握手题时非常关键。

2. ACK:确认有效

ACK 位置 1,表示“确认号字段有效”。

注意不是说“有 ACK 标志就一定只是在确认”,而是说“确认号这个字段此时可以用”。建立连接以后,几乎所有 TCP 报文段都会带 ACK=1。

考试里常见误区是把 ACK 理解成“确认报文段”。实际上,一个报文段可以同时带多个标志,比如 SYN + ACK,这在三次握手第二步里就会出现。

纯 ACK 本身不消耗序号。这也是做题的核心规则之一。

3. FIN:释放连接

FIN = Finish,表示发送方已经没有数据要发了,希望释放连接。

它主要用于四次挥手。和 SYN 一样:

FIN 也会消耗一个序号。

这是挥手题最容易错的地方之一。

4. RST:复位连接

RST = Reset,用于异常情况,表示连接出错,或者一方想强制中止连接。

比如访问一个不存在的端口,或者连接状态异常,可能收到 RST。考题里常把它和 FIN 对比:FIN 是正常结束,RST 是异常复位或强制中断。

5. PSH:尽快交付

PSH = Push,表示接收方应尽快把数据交给应用进程,而不要继续在缓冲区里等待。

这个标志位在考研中一般不会深挖实现细节,更重要的是知道它的含义:提示尽快上交应用层。

6. URG:紧急数据

URG = Urgent,表示紧急指针字段有效,报文段中有紧急数据,应优先处理。

这部分现在工程实践里不算常见,但考题里会把它作为首部字段识别题来考。记法很简单:URG 一出现,就要想到“紧急指针有效”。


三、TCP 首部中的窗口字段,到底表示什么

这个字段是很多人看了很多遍还是不扎实的地方,因为“窗口”这个词在数据链路层、传输层里都出现过,容易混。

TCP 首部里的“窗口”字段,通常指的是接收方通告窗口,也就是英文常说的 rwnd

它的含义是:

接收方告诉发送方:我当前接收缓存里还能接收多少字节。

注意两个关键词。

第一,是“接收方通告”的。也就是说,这个字段不是发送方随便填的,而是接收方根据自己接收缓存的剩余空间,告诉对方一个数。

第二,单位是“字节”,不是“报文段个数”。这和很多链路层协议按帧编号、按帧计数很不一样。TCP 是按字节编号的,所以窗口本质上也是按字节度量的。

可以把它理解成一句非常直白的话:

“你最多还可以继续给我发这么多字节,再多我这边缓存可能就装不下了。”

所以 TCP 首部中的窗口字段体现的是流量控制思想。它解决的不是“网络堵不堵”的问题,而是“接收方来不来得及收”的问题。


四、发送方的窗口大小到底取决于什么

这是一个非常高频考点。

TCP 发送方真正能发送的数据量,不是只看接收方窗口,也不是只看网络拥塞情况,而是同时受两方面约束:

发送窗口 = min(rwnd, cwnd)

这里:

rwnd 是接收方通告窗口,反映接收方处理能力,属于流量控制。
cwnd 是拥塞窗口,反映网络拥塞情况,属于拥塞控制。

所以真正的结论是:

发送方窗口大小取决于接收方通告窗口和拥塞窗口二者中较小者。

如果题目只考流量控制,往往说“发送窗口由接收方通告窗口决定”;
如果题目把拥塞控制也带进来,就要写更完整的版本:min(rwnd, cwnd)

进一步说,发送方“此刻还能继续发送多少”,还要减去那些“已经发出但还没被确认的数据”。所以更细一点地理解是:

  • min(rwnd, cwnd) 决定发送窗口上限
  • 已发送未确认的数据占用了一部分窗口
  • 剩下那部分,才是当前还能再发的数据量

这个在计算题里会体现为“可发送窗口”。


五、MSS 到底是什么,和 MTU 有什么关系

MSS = Maximum Segment Size,最大报文段长度。

更准确地说,MSS 指的是:

一个 TCP 报文段中,数据部分的最大长度。

注意,是TCP 数据部分,不包括 TCP 首部,也不包括 IP 首部。

这个概念常和 MTU 一起出现。

  • MTU:链路层最大传输单元,指一个链路层帧中能承载的网络层数据的最大长度
  • MSS:TCP 一次愿意放进一个报文段里的最大 TCP 负载长度

在不考虑 IP/TCP 选项时,常见以太网环境下:

MSS = MTU - IP首部长度 - TCP首部长度

若以太网 MTU = 1500B,IPv4 首部 20B,TCP 首部 20B,则:

MSS = 1500 - 20 - 20 = 1460B

这也是一道非常常见的计算。

MSS 一般在三次握手时通过 TCP 选项协商。它的作用是尽量让 TCP 报文段大小合适,避免 IP 层分片。


六、三次握手怎么记,为什么是三次,不是两次

三次握手本质上干三件事:

  1. 客户端告诉服务器:我能发,你在吗
  2. 服务器告诉客户端:我能收也能发,我也在
  3. 客户端再告诉服务器:我知道你也能收发了

所以它不只是“打招呼”,而是双方都要确认彼此的发送和接收能力正常。

三次握手标准过程

设客户端初始序号为 x,服务器初始序号为 y

第一次:
客户端 → 服务器
SYN=1, seq=x

含义:请求建立连接。
注意:SYN 消耗一个序号,所以客户端下次发送的序号应从 x+1 开始。

第二次:
服务器 → 客户端
SYN=1, ACK=1, seq=y, ack=x+1

含义:同意建立连接,同时确认收到了客户端的 SYN。
这里服务器自己的 SYN 也消耗一个序号,所以服务器后续序号从 y+1 开始。

第三次:
客户端 → 服务器
ACK=1, seq=x+1, ack=y+1

含义:确认收到了服务器的 SYN。

记忆的核心规则只有三句

第一句:

谁发 SYN,谁的序号就加 1。

第二句:

确认号 = 对方序号 + 1(若对方发的是 SYN/FIN)或 对方序号 + 数据字节数。

第三句:

纯 ACK 不消耗序号。

你会发现,三次握手之所以看起来复杂,其实只是因为同时在记“两条方向各自的序号线”。一旦抓住“各算各的”,就不乱了。

客户端序号线:

x → x+1

服务器序号线:

y → y+1

它们彼此通过 ack 去确认对方已经走到了哪里。

为什么不能两次握手

考研常见表述是:两次握手无法防止失效的连接请求报文段突然又传到服务器,从而导致服务器错误建立连接。更通俗一点说,就是服务器没法确认客户端是否真的收到了自己的确认,也没法确认双方都已进入可通信状态。

所以第三次握手的本质,是让服务器知道:

“我发给你的 SYN+ACK,你确实收到了。”


七、四次挥手怎么记,为什么通常是四次

这块比三次握手更容易乱,因为它体现了 TCP 的全双工特性:两个方向的关闭是分开的。

四次挥手标准过程

设主动关闭方 A, 被动关闭方 B。

第一次:
A → B
FIN=1, seq=u

表示 A 已经没有数据要发了。
注意:FIN 消耗一个序号,所以 A 后续序号变成 u+1

第二次:
B → A
ACK=1, ack=u+1, seq=v

表示 B 知道 A 这边要关了。
这一步只是“确认”,并不代表 B 也立即关闭。

第三次:
B → A
FIN=1, ACK=1, seq=w, ack=u+1

表示 B 自己的数据也发送完了,现在也请求关闭。

第四次:
A → B
ACK=1, seq=u+1, ack=w+1

表示确认收到 B 的 FIN。

为什么通常是四次,不是三次

因为 TCP 是全双工的。

A 不发了,只代表 A → B 这个方向关闭;
但 B → A 方向可能还有数据没发完,所以 B 先发 ACK,等自己数据发完后再发 FIN。

这就是“四次”的根本原因:两个方向分别关闭。

当然,在特殊情况下,B 第二次和第三次可以合并,也就是 ACK 和 FIN 一起发出去,但考试默认记标准四次挥手就够了。

四次挥手最实用的记忆法

只记一句最核心的话:

SYN 和 FIN 都要占一个序号,纯 ACK 不占。

于是所有题都可以机械推:

  • 看到 SYN:序号 +1
  • 看到 FIN:序号 +1
  • 看到数据:序号 + 数据字节数
  • 看到纯 ACK:序号不变

这比死背每一包长什么样更稳。


八、怎么记三次握手和四次挥手,不至于一做题就乱

这类题之所以让人觉得“包太多,太复杂”,本质原因不是包真的多,而是同时在跟踪:

  1. 客户端序号线
  2. 服务器序号线
  3. 哪些标志位消耗序号
  4. ack 到底在确认什么

真正高效的记法,不是背图,而是背规则。

第一条铁律:TCP 序号按字节编号

TCP 的 seq 不是“第几个报文段”,而是本报文段数据部分第一个字节的编号

所以一旦带数据,序号前进量就是数据字节数。

第二条铁律:SYN、FIN 各占一个序号

这是做连接管理题最关键的规则。握手和挥手里,真正让序号 +1 的,往往就是 SYN 和 FIN。

第三条铁律:纯 ACK 不占序号

很多题错就错在把 ACK 也当成“占一个位置”。其实纯 ACK 只是确认,不携带新数据,也不申请建立/释放,因此不额外消耗序号。

第四条铁律:ack 表示“我期待收到你的下一个字节编号”

这句话特别重要。

所以 ack 不是“我收到了哪个编号”,而是“我已经收到了你前面的内容,下一次请从这个编号开始发”。

这样一来,ack = 已正确收到的最后一个字节编号 + 1

如果收到的是 SYN 或 FIN,因为它们也占一个序号,所以确认时也要加 1。

做题模板

以后凡是握手挥手题,建议直接画两条线:

上面写客户端序号变化,下面写服务器序号变化。
每来一个报文段,就只做三件事:

  1. 看谁发
  2. 看它带没带 SYN / FIN / 数据
  3. 改它自己的 seq,改对方给它的 ack

这么做会比背图稳得多。


九、例题:40Gb/s 的 TCP 多久会发生 32 位序号绕回

题目本质是在问:

TCP 序号字段 32 位,最多能表示 2^32 个不同序号。
如果一直高速发送数据,用完这一圈需要多长时间?

因为 TCP 序号是按字节编号的,所以可用字节数是一圈:

2^32 B

线路速率是:

40 Gb/s = 40 × 10^9 bit/s

换成字节每秒:

40 × 10^9 ÷ 8 = 5 × 10^9 B/s

于是发生序号绕回的时间为:

2^32 ÷ (5 × 10^9) s

又因为:

2^32 = 4.294967296 × 10^9

所以:

时间 ≈ 4.294967296 × 10^9 ÷ 5 × 10^9
≈ 0.8589934592 s

约等于:

0.859 s

本题结论

TCP 在 40Gb/s 的线路上,若充分利用带宽,大约 0.859 秒就会发生一次 32 位序号绕回。

这题考什么

它考的是三个点:

第一,TCP 序号按字节编号,而不是按报文段编号。
第二,32 位序号空间是一圈 2^32
第三,速率单位要从 bit/s 换成 B/s。

最容易错的地方

最常见错误有两个。

第一个错误,是把 2^32 当成 bit 数,而不是字节数。
第二个错误,是忘记 1B = 8bit,没有把 40Gb/s 换算成字节每秒。


十、TCP 的窗口机制和数据链路层滑动窗口、GBN 为什么“看起来很像”

你这个感觉完全对。它们确实有共同思想,所以看起来很像;但又不能直接画等号。

先说它们为什么像

它们都用了“滑动窗口”思想。

所谓滑动窗口,本质上就是:

  • 发送方不必每发一份数据就停下来等确认
  • 可以连续发送多个单位的数据
  • 收到确认后,窗口向前滑动,继续发送后面的数据

这和停止-等待相比,效率明显高很多。所以数据链路层的 GBN、SR,以及传输层的 TCP,都使用了窗口思想。

它们也都涉及:

  • 序号
  • 确认
  • 超时重传
  • 连续发送
  • 流水线传输

所以初学时把 TCP 想成“更复杂的滑动窗口协议”是很自然的。


十一、但 TCP 和 GBN 不能简单等同,差别很大

1. 所在层次不同

GBN、SR 是数据链路层可靠传输机制,通常解决的是一段链路上的帧传输问题
TCP 是传输层协议,解决的是端到端进程之间的可靠传输问题

这一点决定了 TCP 面对的环境更复杂。它跨越多个路由器、多个链路,必须考虑网络拥塞、接收缓存、端到端时延变化等问题,而链路层窗口协议往往只针对单跳链路。

2. 编号单位不同

GBN 一般按“帧”编号。
TCP 按“字节”编号。

这会直接影响做题方式。TCP 的 seq 和 ack 都是字节级的,因此一个报文段发送了多少字节,序号就推进多少。

3. TCP 同时做流量控制和拥塞控制,GBN 主要不是干这个的

GBN 的重点是可靠传输和差错恢复。
TCP 除了可靠传输,还要做:

  • 流量控制:别把接收方撑爆
  • 拥塞控制:别把网络打爆

所以 TCP 的发送窗口不是一个简单固定窗口,而是同时受 rwndcwnd 影响。

这也是 TCP 比 GBN 复杂得多的根本原因。

4. 确认机制相似,但 TCP 更灵活

经典 GBN 是累计确认,也就是确认到某一帧为止之前都收到了。
TCP 默认也是累计确认,所以这也是你觉得它像 GBN 的一个重要原因。

但 TCP 比 GBN 灵活得多。现代 TCP 中可能还有:

  • 延迟确认
  • 重复 ACK
  • 快重传
  • 选择确认 SACK

所以 TCP 不是教材里那个“纯粹的 GBN”。它只是保留了“累计确认”这一核心味道。

5. 失序处理方式不同

经典 GBN 中,接收方通常丢弃失序到达的帧,只确认按序到达的最后一帧。
TCP 在教材层面常强调“累计确认、按序交付”,所以也有类似味道;但实际实现里,TCP 往往会缓存失序报文段,并借助 SACK 等机制优化重传。

所以从考研做题角度,可以记成:

TCP 在确认风格上更接近累计确认,但整体并不等同于 GBN。

6. 重传策略不同

GBN 一旦某帧丢失,发送方超时后往往从该帧开始,把后面已经发过的都重传。
TCP 不一定这样“整段回退”,它有更复杂的重传判断方式,例如基于超时、基于重复 ACK 的快重传等。


十二、怎么在考试里快速区分“TCP 窗口”和“数据链路层滑动窗口”

我觉得可以抓下面这条主线:

如果题目强调“端到端、字节流、接收窗口、拥塞窗口、三次握手、四次挥手”

那基本就是 TCP 视角。

如果题目强调“帧编号、发送窗口 WT、接收窗口 WR、GBN、SR、停止等待、链路利用率”

那基本就是数据链路层可靠传输视角。

再进一步压缩成一句口诀:

链路层窗口重在差错恢复,TCP 窗口还要兼顾流量控制和拥塞控制。


十三、这一部分最容易错的点,最好单独记一下

第一,UDP 面向报文,保留消息边界;TCP 面向字节流,不保留消息边界。
第二,TCP 的序号和确认号都是按字节编号,不是按报文段编号。
第三,SYN 和 FIN 各消耗一个序号,纯 ACK 不消耗。
第四,TCP 首部中的窗口字段是接收方通告窗口,体现流量控制。
第五,发送窗口真正取决于 min(rwnd, cwnd)
第六,MSS 指 TCP 数据部分最大长度,不含 TCP/IP 首部。
第七,TCP 的累计确认机制看起来像 GBN,但 TCP 不是简单的 GBN。
第八,三次握手是为了双方都确认彼此的发送、接收能力;四次挥手是因为 TCP 全双工,两个方向要分别关闭。


十四、最后把这部分压缩成一版考前速记

TCP 与 UDP 的报文区别,最核心就是一句:

UDP 面向报文,保留边界;TCP 面向字节流,不保留边界。

TCP 报文段标志位,常考 6 个:

URG、ACK、PSH、RST、SYN、FIN

其中最重要的是:

  • SYN:建立连接,占 1 个序号
  • ACK:确认有效,纯 ACK 不占序号
  • FIN:释放连接,占 1 个序号
  • RST:异常复位

窗口字段表示:

接收方当前还能接收多少字节。

MSS 表示:

TCP 数据部分最大长度。

发送窗口取决于:

min(rwnd, cwnd)

三次握手记法:

SYN → SYN+ACK → ACK

四次挥手记法:

FIN → ACK → FIN → ACK

做一切握手挥手题,只抓三条规则:

  • SYN 加 1
  • FIN 加 1
  • 纯 ACK 不加 1
  • 数据按字节数推进

40Gb/s 下 32 位序号绕回时间:

2^32 B ÷ (40×10^9 ÷ 8) B/s ≈ 0.859 s

TCP 窗口和 GBN 的关系:

思想相似,都是滑动窗口;但 TCP 是端到端、按字节、兼顾流量控制和拥塞控制,不能简单等同于 GBN。

TCP 首部字段题、握手挥手题、窗口计算题的做题模板

前面把 TCP 的核心概念捋顺之后,真正到做题时,最需要的其实不是再背一遍定义,而是有一套能直接落笔、直接推数、直接排除错误选项的模板。TCP 这一章最典型的题,基本都可以归到三类:首部字段识别题、握手挥手分析题、窗口与确认计算题。这三类题看起来信息量很大,但真正上手时,判断路径其实很固定。

这一节就专门把这三类题的“固定做法”单独整理出来。后面复习时,只要把模板拿出来套,很多题就不会再乱。


一、TCP 首部字段题的做题模板

这类题最常见的出法,是给出一个场景,让判断应该使用哪个字段,或者直接问某个字段的作用,也可能把 TCP 和 UDP 的首部放在一起比较。看起来像记忆题,但真正想做稳,不能死记硬背,而是要按“这个字段解决什么问题”来分类。

做首部字段题时,我一般先不急着看选项,而是先问自己:题目问的到底是下面哪一类能力。

第一类,是“寻址和复用”。如果题目问的是“哪个进程和哪个进程通信”“区分同一主机上的不同应用进程”,那优先想到源端口和目的端口。

第二类,是“可靠传输和按序交付”。如果题目问的是“哪一部分保证有序”“哪一部分表示发送字节的位置”“确认到了哪里”,那优先想到序号和确认号。序号负责给字节编号,确认号负责说明下一次期望收到哪个字节。

第三类,是“连接建立和释放”。如果题目涉及三次握手、四次挥手、异常复位,那优先想到标志字段,尤其是 SYN、ACK、FIN、RST。

第四类,是“流量控制”。如果题目问接收方还能收多少、发送方最多还能发多少,优先想到窗口字段。

第五类,是“紧急数据和立即交付”。题目出现“紧急”“优先处理”,对应 URG 和紧急指针;题目出现“尽快提交应用层”,对应 PSH。

第六类,是“检错”。如果题目问首部中哪个字段用于差错检测,想到校验和。

也就是说,首部字段题不是一堆零散字段,而是按照功能一块一块记。这样做题时,先定位功能,再映射字段,速度会快很多。


二、TCP 首部字段题的速判表

为了后面复习更顺,我把最常见字段和考法压缩成一张表。考试时很多选项其实都能靠这张表快速排除。

字段作用题目里常见表述
源端口、目的端口标识发送/接收进程进程复用与分用、端到端逻辑通信
序号 seq本报文段数据部分第一个字节的编号按字节编号、可靠传输、有序交付
确认号 ack期望收到对方的下一个字节编号确认、累计确认、收到哪里为止
数据偏移TCP 首部长度首部多长、数据从哪里开始
标志位连接管理与状态控制SYN、ACK、FIN、RST、PSH、URG
窗口接收方当前可接收的数据量流量控制、接收缓存剩余空间
校验和检测差错差错检测
紧急指针紧急数据末尾位置URG、生效条件

这类题的常见陷阱有两个。

第一个陷阱,是把“窗口”误以为是发送方说了算。实际上 TCP 首部中的窗口字段,是接收方通告给发送方的,表示“我还能收多少”。

第二个陷阱,是把“确认号”理解成“已经收到的最后一个字节编号”。更准确的说法应该是:确认号表示期望收到的下一个字节编号。这两个说法看起来很像,但考试时如果表述严格,最好用后者。


三、遇到 TCP 首部字段题时,固定答题顺序怎么走

如果是选择题,我建议按下面的顺序过脑子。

先看题干关键词。
出现“连接建立”看 SYN。
出现“连接释放”看 FIN。
出现“确认”看 ACK 和确认号。
出现“流量控制”看窗口。
出现“复位”看 RST。
出现“紧急”看 URG。
出现“尽快交付”看 PSH。

如果是简答题,就不要只写字段名称,而应该写成“字段 + 作用 + 场景”三连。

比如问窗口字段的含义,最稳的写法不是只写“流量控制”,而是写:

“窗口字段由接收方填写,表示接收方当前还能接收的字节数,用于实现 TCP 的流量控制,限制发送方的发送速率。”

这种写法在考试里更容易拿满分,因为它不是只记住了名词,而是把逻辑关系写完整了。


三次握手和四次挥手题的做题模板

握手挥手题之所以让人头疼,根本原因不是步骤多,而是它同时考两个方向的序号变化。只要能把两个方向拆开,题目立刻就顺了。

我做这类题时,固定先做一件事:画两条序号线。

上面一条写客户端。
下面一条写服务器。

然后每来一个报文段,只检查四个信息:

  1. 谁发的
  2. 带了哪些标志位
  3. 有没有数据
  4. 对方应该确认到哪里

只要坚持这样做,哪怕题目把包数增加、把数据夹在中间,甚至加入 FIN、SYN、确认号混合,你都不会乱。


四、握手挥手题最核心的四条规则

这四条规则比背图更重要。几乎所有题都靠它们推出结果。

第一条,TCP 按字节编号。
序号不是报文段编号,而是字节编号。

第二条,SYN 和 FIN 各消耗一个序号。
只要报文段带 SYN 或 FIN,就会让本方向序号前进 1。

第三条,纯 ACK 不消耗序号。
如果只是确认,没有数据,也没有 SYN/FIN,那么 seq 本身不因为 ACK 而前进。

第四条,ack 表示“期望收到对方的下一个字节编号”。
也就是说,确认号 = 对方已正确发送到的最后位置 + 1。

这四条规则基本就是所有握手挥手题的底层算法。


五、三次握手题的标准模板

设客户端初始序号为 x,服务器初始序号为 y``。

第一步,客户端发起连接:

SYN=1, seq=x

因为 SYN 占一个序号,所以客户端后续序号从 x+1 开始。

第二步,服务器同意连接:

SYN=1, ACK=1, seq=y, ack=x+1

这里服务器确认了客户端的 SYN,所以确认号是 x+1。同时服务器自己也发了 SYN,因此服务器后续序号从 y+1 开始。

第三步,客户端确认:

ACK=1, seq=x+1, ack=y+1

因为这是纯 ACK,没有数据,没有 SYN/FIN,所以客户端的 seq 仍然是 x+1

把这三步压缩成一个固定模板就是:

次数方向标志seqack
1C → SSYNx无效
2S → CSYN + ACKyx+1
3C → SACKx+1y+1

以后只要题目一出现握手,直接把这个表默写出来,再按题目给的具体数字代进去。


六、四次挥手题的标准模板

设主动关闭方 A,初始关闭时该方向当前序号为 u;被动关闭方 B 当前序号为 v

第一步,A 发 FIN:

FIN=1, seq=u

因为 FIN 占一个序号,所以 A 后续序号从 u+1 开始。

第二步,B 回 ACK:

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

注意这里通常是纯 ACK,所以 B 的 seq 不因为 ACK 改变。

第三步,B 自己也发 FIN:

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

如果 B 在第二次和第三次之间没有再发送数据,那么常直接有 w=v
如果中间发过数据,那 w 就应等于发完那些数据后的新序号。

第四步,A 回 ACK:

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

这一步纯 ACK,不再额外消耗序号。

标准模板可以记成:

次数方向标志seqack
1A → BFINu旧值或无关
2B → AACKvu+1
3B → AFIN + ACKwu+1
4A → BACKu+1w+1

最容易错的地方,就是第二步和第三步里 B 的 seq。很多人会机械地把第二步 ACK 当成也占一个序号,这是错误的。纯 ACK 不占序号,所以如果中间没发数据,那么第二步和第三步的起始 seq 可以一样。


七、握手挥手题的万能推题步骤

以后碰到任何 TCP 握手挥手题,不管它是选择题还是大题,都可以用下面这个顺序。

先写清初始序号。
如果题目给了 ISN=100seq=8000 之类,先在两条线各自标好。

然后按报文段顺序推进。
每看到一个报文段,就判断它是否包含:

  • SYN
  • FIN
  • 数据
  • 纯 ACK

接着更新本方向序号。
更新规则非常机械:

  • 带 SYN:本方向 +1
  • 带 FIN:本方向 +1
  • 带数据:本方向 + 数据字节数
  • 纯 ACK:本方向不变

最后更新对方确认号。
确认号始终写成:

ack = 期望收到的对方下一个字节编号

只要坚持“先更新发送方 seq,再更新接收方 ack”,这类题会非常稳。


窗口计算题的做题模板

TCP 窗口题比握手挥手更容易让人乱,因为它同时可能混着:

  • 接收窗口 rwnd
  • 拥塞窗口 cwnd
  • 发送窗口
  • 已发送未确认数据
  • 确认号
  • 可继续发送的数据量

如果没有模板,很容易每个词都认识,但整道题算不明白。

这类题最重要的是先把“窗口”拆成三个层次。

第一个层次,是接收方窗口 rwnd,它表示接收方还能收多少。
第二个层次,是拥塞窗口 cwnd,它表示当前网络允许发送方发多少。
第三个层次,是发送方实际可用窗口,它由前两者较小值决定,再扣除已发送未确认部分。

真正做题时,先固定记住一个总公式:

发送窗口上限 = min(rwnd, cwnd)

然后再记:

当前还能发送的数据量 = 发送窗口上限 - 已发送未确认的数据量

只要题目有窗口、有确认号、有已发未确认字节数,基本都是按这个思路算。


八、窗口题里几个名词的固定理解

为了防止后面一看到题干就被绕晕,最好先把几个词钉死。

“发送窗口”不是“已经发送出去的数据”,而是“允许发送但尚未确认的序号范围”。

“可用发送窗口”才是此刻还能继续发出去的部分。

“接收窗口”是接收方通告的剩余缓存空间。

“确认号”表示接收方目前按序收到了哪里,因此会决定发送窗口左边界能否右移。

也就是说,窗口题本质上是在问两件事:

第一,发送方理论上最多能占用多大窗口。
第二,在这个窗口里,已经用了多少,还剩多少可发。


九、窗口计算题的标准步骤

以后只要碰到 TCP 窗口题,建议固定按下面四步走。

第一步,找 rwndcwnd
如果题目只给流量控制信息,没有拥塞控制,那就默认发送窗口主要看 rwnd
如果两个都给,就先取最小值。

第二步,找“已发送未确认的数据量”。
这个量通常可以通过“已发送到哪个序号”“已确认到哪个序号”来求。

一般可写成:

已发送未确认 = 已发送最后一个字节编号 - 已确认到的前一个字节编号

如果题目直接给“还有多少未确认数据”,那更简单,直接用。

第三步,求当前还能发送的数据量。
公式就是:

还能发送 = min(rwnd, cwnd) - 已发送未确认

第四步,检查结果是否合理。
如果算出来是负数,说明此刻不能继续发;
如果算出来是 0,说明窗口已满;
如果大于 0,说明还可以继续发这么多字节。

这个模板适合绝大多数窗口选择题和计算题。


十、一个最常见的窗口题型,怎样套模板

比如题目说:

“发送方已发送 3000B,已确认 2000B,接收方通告窗口为 4000B,拥塞窗口为 5000B,问当前还能发送多少字节?”

这类题看起来字很多,但就是机械套公式。

先求发送窗口上限:

min(rwnd, cwnd) = min(4000, 5000) = 4000B

再求已发送未确认:

3000 - 2000 = 1000B

于是当前还能发送:

4000 - 1000 = 3000B

这就是答案。

这类题真正难的地方,不在算,而在分清“已发送”和“已确认”不是一回事。很多人会把已经确认的也算进占用窗口里,导致结果偏小。


十一、确认号与窗口结合题,最容易错在哪

这类题经常会问:

“接收方发送确认号 ack=5001,这表示什么?”

标准理解是:

这表示接收方已经按序收到了编号到 5000 为止的数据,下一次希望发送方从 5001 开始发送。

如果这时又给出接收窗口为 2000B,那么含义就是:

发送方接下来最多可以在 5001 开始的基础上,再占用 2000B 的接收窗口范围。

也就是说,确认号决定左边界,窗口大小决定右边界。

这个思想特别重要。以后看到“ack + 窗口”放在一起,就要想到:ack 定起点,window 定宽度。


十二、窗口题、握手题、首部字段题之间其实是连着的

很多人复习时把这三类题分开记,结果越记越散。实际上,它们之间是一条线。

首部字段题,解决的是“每个字段干什么”。
握手挥手题,考的是“seq、ack、SYN、FIN 如何联动”。
窗口计算题,考的是“ack、window、已发送数据如何联动”。

所以从根上说,这一章真正反复出现的核心只有四个量:

  • seq
  • ack
  • 标志位
  • 窗口

做题时只要盯住这四个量,题干再长,也不会完全失控。


最后压缩成一版“考场速用模板”

TCP 首部字段题,先按功能分类:

  • 端口:进程复用与分用
  • seq:按字节编号
  • ack:期望收到的下一个字节编号
  • 标志位:连接建立、释放、复位、紧急、推送
  • 窗口:接收方还能接收多少字节
  • 校验和:差错检测

握手挥手题,只记四条规则:

  • SYN 占 1 个序号
  • FIN 占 1 个序号
  • 纯 ACK 不占序号
  • 数据按字节数推进序号

做题顺序固定为:

  1. 画两条序号线
  2. 看谁发
  3. 看有没有 SYN/FIN/数据
  4. 更新本方向 seq
  5. 用“期望收到的下一个字节编号”写 ack

窗口题只记两个公式:

发送窗口上限 = min(rwnd, cwnd)

当前还能发送 = min(rwnd, cwnd) - 已发送未确认

再配一句理解:

ack 决定左边界,window 决定窗口宽度。

TCP 这章最容易出错的典型陷阱清单

TCP 这一章很典型的一个问题是,单看每个知识点都不算难:三次握手能背,四次挥手也见过,窗口字段、确认号、MSS、序号这些概念也都认识。但一到做题,尤其是一道题里同时出现多个字段、多次交互、多个报文段的时候,就特别容易乱。很多错误并不是不会,而是“似懂非懂”,最后在细节处丢分。

这一节就专门把 TCP 里最容易出错的陷阱集中整理一下。后面复习时,光看这份“坑点清单”,往往比再看一遍概念更有用。


一、把 TCP 看成“面向报文”而不是“面向字节流”

这是 TCP 最根本、也最容易在后面反复连锁出错的地方。

很多人在刚学 TCP 时,会不自觉地把它想成“和 UDP 一样,也是一个一个数据包地传,只不过更可靠”。这个理解很容易导致后面很多题都做偏,因为 TCP 和 UDP 在传输对象上就不是一回事。

UDP 面向报文,应用层交给它一条报文,它基本就按这条报文发,接收时也按一条完整报文交给应用层,因此 UDP 保留报文边界。

TCP 面向字节流。应用层写入的是一串字节,TCP 只负责把这串字节可靠、按序送到对方,并不保留“这部分原来是一次 write 发的,那部分原来是另一次 write 发的”这种边界信息。一次应用层发送,可能被拆成多个报文段;多次应用层发送,也可能被合并进一个报文段。

这个地方一旦没想清楚,后面就容易犯两个典型错误。

第一个错误,是误以为 TCP 的序号对应“第几个报文段”。其实 TCP 的序号对应的是字节位置
第二个错误,是看到“发送了一个 TCP 报文段”,就想当然地认为接收方也“一次收到一个完整单位”。实际上,接收方拿到的是字节流。

所以这一章最先要固定的一句话就是:

TCP 按字节编号,面向字节流;UDP 按报文组织,面向报文。


二、把 seq 当成“报文段编号”,而不是“字节编号”

这是 TCP 计算题里最常见的错误之一。

TCP 首部中的序号 seq,不是“这是第几个报文段”,而是:

本报文段数据部分第一个字节的编号。

这句话必须咬得很死,因为它会直接影响三类题:

第一类,是握手挥手题。
第二类,是带数据的确认号计算题。
第三类,是序号绕回题。

如果一个 TCP 报文段携带了 100B 数据,起始序号是 3001,那么它覆盖的数据范围就是 3001 到 3100,下一个报文段若紧接着发,序号就应从 3101 开始。

很多人错在把“发了一个报文段”就当成“序号 +1”。这在 TCP 中是错误的。只有两种特殊控制位会无论是否带数据都额外占一个序号,那就是 SYN 和 FIN。

所以序号推进的真正规则应该是:

  • 发数据:序号加数据字节数
  • 发 SYN:序号加 1
  • 发 FIN:序号加 1
  • 纯 ACK:序号不变

这个规则是 TCP 整章最核心的计算底座。


三、把 ack 理解成“收到了哪个编号”,而不是“下一个想收哪个编号”

确认号也是 TCP 里非常容易半懂不懂的点。

很多人在脑中会把它理解为“我收到了编号 1000 的数据,所以 ACK=1000”。这种理解在直觉上似乎也说得过去,但严格来说是不对的。

TCP 的 ack 的准确含义是:

接收方期望收到的下一个字节编号。

也就是说,如果 ack=1001,真正的含义不是“我只收到了 1001”,而是:

“到 1000 为止的字节我都已经按序收到了,下一次请从 1001 开始发。”

这也是为什么 TCP 使用累计确认。确认号一旦前进到某个位置,就表示在此之前的按序数据都已经确认了。

这个坑最容易在带数据的题里出问题。比如一个报文段起始 seq=500,数据长度 200B,那么它覆盖字节编号 500 到 699。如果对方正确收到并确认,那么返回的 ack 应该是 700,而不是 699,也不是 500。

所以可以把 ack 永远翻译成一句固定的话:

ACK 不是“收到哪”,而是“下次该从哪开始发”。


四、忘记 SYN 和 FIN 都会占用一个序号

这可以说是连接管理题里最致命的坑。

很多人知道数据会让序号前进,却忘了 SYN 和 FIN 也会各占一个序号。于是三次握手、四次挥手的 seq 和 ack 一算就错。

必须牢牢记住:

SYN 占 1 个序号,FIN 占 1 个序号,纯 ACK 不占序号。

这句话是做握手挥手题的第一铁律。

比如客户端发送:

SYN=1, seq=100

那么服务器确认时就必须写:

ack=101

因为 SYN 本身也占用了一个序号。

再比如 A 发送:

FIN=1, seq=800

那么 B 确认时应写:

ack=801

这和“带了 1B 数据所以 +1”在形式上很像,但来源不同。它不是数据长度,而是控制位 FIN 本身占了一个序号。

以后只要看到题目中出现 SYN 或 FIN,就应该立刻在脑中亮起一个提醒:

这里要 +1。


五、误以为“凡是 ACK 都会让 seq 加 1”

这通常是上一个坑的连带错误。

因为很多人背握手挥手时,只看到一连串“101、102、103”之类的数字变化,就误以为 ACK 也会推动 seq 前进。实际上,ACK 只是表示确认号字段有效,纯 ACK 本身不占用序号。

所以如果一个报文段只是:

ACK=1, seq=x, ack=y

而没有数据、没有 SYN、没有 FIN,那么这个报文段发完以后,发送方自己的序号仍然还是 x,不会因为“发了一个 ACK”就自动变成 x+1。

这个坑在四次挥手第二步和第四步最常见。

A 发 FIN 后,B 会先回一个 ACK,这个 ACK 如果没有带数据,那么 B 的 seq 不变。后面 B 再发 FIN 时,如果中间也没发数据,那么它发 FIN 时的 seq 和刚才那个 ACK 的 seq 往往是一样的。

很多题就专门利用这一点设陷阱,让人误把 ACK 当成也消耗序号,最后 seq 全线错位。


六、把 TCP 首部中的“窗口”误当成发送方自己的剩余发送能力

TCP 首部中的窗口字段很容易望文生义,以为“窗口”就是发送方能发多少。其实首部中的窗口字段,是接收方通告给发送方的窗口,也就是接收方当前还能接收多少字节。

换句话说,它不是发送方自言自语写进去的,而是接收方告诉对方:

“我这边接收缓存还有这么多空间,你最多还能往我这里压这么多字节。”

所以这个字段反映的是流量控制,约束的是发送方的发送速度,依据的是接收方的接收能力。

很多题里会问“窗口字段的含义是什么”,最稳的答法不是只写“TCP 的窗口大小”,而是写:

窗口字段表示接收方当前可接收的数据量,用于通知发送方进行流量控制。

这样表意最完整,也最不容易混成“发送方窗口”。


七、以为发送窗口只由 rwnd 决定,忘了还有 cwnd

如果只学了流量控制,很多人会觉得“窗口大小就是接收方通告窗口 rwnd”。这在只讨论流量控制的题目里不算错,但如果题目把拥塞控制也带进来,这个答案就不完整了。

TCP 发送方真正的发送窗口上限,应该取:

min(rwnd, cwnd)

其中:

  • rwnd 反映接收方接收能力
  • cwnd 反映当前网络拥塞状况

所以发送方不是“想发多少就发多少”,也不是“只要接收方装得下就行”,而是既不能把接收方撑爆,也不能把网络打爆。

这个点经常在选择题里考表述的完整性。
如果题目只在讲流量控制,可以说发送窗口受接收方窗口影响;
如果题目明确把拥塞控制也纳入条件,就必须写完整:

发送窗口由接收窗口和拥塞窗口中较小者决定。


八、把“发送窗口大小”和“当前还能继续发送的数据量”混为一谈

这是窗口计算题里特别容易糊涂的地方。

“发送窗口大小”通常是说发送方理论上允许占用的窗口范围,常由 min(rwnd, cwnd) 决定。
但“当前还能继续发送多少”,并不等于这个窗口上限,因为窗口里可能已经装了一部分“已发送但未确认的数据”。

所以真正能再发多少,应该是:

当前可发送量 = min(rwnd, cwnd) - 已发送未确认数据量

这两个概念必须分开。

很多题里给出:

  • 接收窗口 5000B
  • 拥塞窗口 6000B
  • 已发送未确认 2000B

然后问“当前还能发多少”。
这时答案不是 5000B,而是:

5000 - 2000 = 3000B

也就是说,窗口上限是 5000B,但里面已有 2000B 在“占位”,剩余可发只有 3000B。

所以看到窗口题,先别急着代公式,一定先问自己:
题目问的是“窗口上限”,还是“此刻还能发多少”。


九、看到确认号就只会机械相减,不理解“左边界”和“右边界”

窗口题里还有一个非常容易被忽视的本质:确认号和窗口字段其实是在一起定义发送空间。

确认号决定的是左边界,表示发送方已经确认到了哪里。
窗口字段决定的是右边界相对左边界还能向前开多宽

所以如果接收方发来:

ack = 5001, window = 3000

这表示:

“5000 及以前的字节我都按序收到了,你接下来可以从 5001 开始继续发,并且最多还可以向前占用 3000B 的接收窗口空间。”

很多人做题时只会把窗口当作一个孤立数字看,没把它和确认号结合起来理解,这样一遇到图示题、区间题、发送窗口滑动题就容易蒙。

真正稳妥的理解是:

ack 定起点,window 定宽度。


十、把 MSS 和“整个 TCP 报文段长度”混淆

MSS 也是一个特别容易因为名字而想当然理解错的概念。

MSS 叫最大报文段长度,但它指的并不是“整个 TCP 报文段总长度”,而是:

TCP 报文段中数据部分的最大长度。

也就是说,MSS 不包括 TCP 首部,也不包括 IP 首部。

很多人看到“最大报文段长度”就本能觉得是整个段从头到尾的长度,这样一做 MTU 相关题就会出错。

最常见关系是:

MSS = MTU - IP首部长度 - TCP首部长度

例如以太网 MTU=1500B,IPv4 首部 20B,TCP 首部 20B,那么:

MSS = 1500 - 20 - 20 = 1460B

如果把 MSS 误当成整个 IP 数据报长度,或者误当成含首部的 TCP 总长度,结果都会错。

所以这个点最稳的记法就是:

MSS 只看 TCP 负载,不看首部。


十一、把 MSS 和 MTU 看成一回事

MSS 和 MTU 经常一起出现,因此很多人会顺手把它们混成一个概念。

但这两个量不在同一层。

MTU 是数据链路层概念,表示链路层帧中可承载的网络层数据的最大长度。
MSS 是传输层概念,表示 TCP 数据部分最大长度。

所以 MTU 更靠下,MSS 更靠上。
MSS 往往是为了适配 MTU,避免 IP 分片而确定的。

如果题目同时出现 MSS 和 MTU,要立刻反应过来:这不是同义替换,而是上下层之间的约束关系。


十二、误以为三次握手只是“打招呼”,没抓住其真实作用

如果只是死背“三次握手建立连接”,一到选择题问“为什么要三次,不是两次”,就容易答得很虚。

三次握手的本质,不是礼貌性打招呼,而是双方要确认:

  • 我能发
  • 我能收
  • 你能发
  • 你能收

换句话说,双方都要确认彼此收发能力正常,并完成初始序号同步。

所以三次握手第二步不是单纯回复一句“好”,而是服务器一边确认客户端的 SYN,一边把自己的 SYN 发出去;第三次握手则是客户端确认服务器的 SYN 已经收到。

如果这个逻辑没搞清,一到题目变形成“为什么两次不够”“为什么第三次必要”“失效连接请求报文段为何会出问题”时,就只能靠死记硬背,很容易答乱。


十三、误以为四次挥手是“规定动作”,没理解为什么通常需要四次

同样地,四次挥手如果只背流程,不理解原因,也很容易在题目变形时出问题。

四次挥手之所以通常是四次,不是因为 TCP 人为规定要四次,而是因为 TCP 是全双工,两个方向的关闭要分开进行。

A 发 FIN,只表示 A 这边没有数据要发了,即 A → B 这个方向准备关闭。
但这并不意味着 B → A 方向也立刻没数据了,所以 B 先回一个 ACK,等自己数据发送完毕后,再发 FIN。

这才形成了“FIN → ACK → FIN → ACK”的四步。

如果没抓住“两个方向独立关闭”这个本质,就会对很多变形题感到困惑,比如:

  • 为什么不能总是三次挥手
  • 为什么第二次和第三次有时能合并
  • 为什么收到 FIN 后不一定马上也发 FIN

这些问题的答案,本质都来自“全双工、双向独立关闭”。


十四、看到四次挥手就忘了 TIME-WAIT 的意义

TIME-WAIT 是 TCP 里另一个高频但很容易背得空洞的点。

很多人只记得“主动关闭方最后要进入 TIME-WAIT,等待 2MSL”,但不知道为什么,于是一到选择题就容易在表述上被干扰。

TIME-WAIT 的主要作用通常可以归纳成两个。

第一,保证最后一个 ACK 能到达。
如果主动关闭方发出的最后 ACK 丢失,那么被动关闭方会重传 FIN。主动关闭方在 TIME-WAIT 状态下还能重发 ACK。

第二,防止旧连接中的延迟报文段影响后续新连接。
等待 2MSL,可以让网络中该连接残留的旧报文段基本失效。

如果这两个作用只记住一句模糊的“避免出错”,做题时就不牢。最好直接记成:

TIME-WAIT = 防最后 ACK 丢失 + 防旧报文干扰新连接。


十五、把“可靠传输”简单理解成“永远不会丢”

TCP 可靠,不等于物理上永远不丢包。
TCP 可靠的真正含义是:即使网络中可能丢失、失序、重复,TCP 也通过确认、重传、排序、校验等机制,尽量保证应用层最终拿到正确、按序、不重复的数据流。

这个点在概念判断题里很容易出“语言陷阱”。

比如题目说:

“TCP 可靠传输是指在传输过程中不会发生丢包。”

这种说法就是错的。
网络中当然可能丢包,TCP 的可靠性恰恰是建立在“可能丢、但能补救”的机制上。

所以以后看到“可靠”二字,不要把它理解成“绝不出错”,而要理解成“通过协议机制保证正确交付”。


十六、把 TCP 误当成数据链路层 GBN 的简单翻版

这个坑通常出现在学完数据链路层滑动窗口协议之后。

TCP 确实和 GBN、滑动窗口有相似性,比如都有序号、确认、窗口、超时重传、流水线发送,所以初学时会觉得“TCP 不就是更复杂一点的 GBN 吗”。

这种感觉不算完全错,但如果直接把它们等同起来,就会出问题。

TCP 和 GBN 至少有几个根本差异。

首先,层次不同。
GBN 是数据链路层协议思想,TCP 是传输层协议。

其次,编号单位不同。
GBN 通常按帧编号,TCP 按字节编号。

再次,TCP 除了可靠传输,还要处理流量控制和拥塞控制。
GBN 主要不是为了解决网络拥塞问题设计的。

最后,TCP 的确认与重传机制更复杂,实际实现中还可能有延迟确认、重复 ACK、快重传、SACK 等机制,不能简单套成“丢一个就全回退”。

所以更稳的表述应该是:

TCP 在确认和窗口思想上与滑动窗口协议相似,但它不是简单等同于 GBN。


十七、把“累计确认”理解成“只能确认一个报文段”

TCP 的累计确认机制也是一个很容易被表面化理解的点。

所谓累计确认,不是“每次只确认当前这个报文段”,而是:

确认号一旦推进到某个位置,就表示这个位置之前按序到达的数据都已经收到了。

例如 ack=5001,并不是只确认一个“5000 号包”,而是确认到 5000 为止的所有按序字节都已收到。

这个点如果没理解,一到判断题里出现“TCP 每收到一个报文段只确认该报文段”这种说法,就很容易误判。


十八、序号绕回题里忘记单位换算

这类题属于计算并不难,但很容易因为单位而翻车。

TCP 序号 32 位,序号空间是一圈 2^32
关键是:这个 2^32 的单位是字节,不是 bit,也不是报文段个数。

如果题目再给链路速率,比如 10Gb/s、40Gb/s,那么必须先把速率从 bit/s 换成 B/s,再去计算:

时间 = 2^32 B ÷ 发送速率(B/s)

最容易错的地方通常有两个。

第一,忘记 TCP 按字节编号,把 2^32 误当成 bit。
第二,忘记 1B = 8bit,直接拿 bit/s 去除 byte 数。

所以以后只要看到“TCP 序号绕回”几个字,先在脑中自动补一句:

先统一单位,序号空间按字节算。


十九、把“建立连接需要三次”死记成绝对格式,不会处理变形题

很多学生背熟的是一个标准图:

SYN → SYN+ACK → ACK

但题目一旦变形,比如问:

  • 第三次握手能不能携带数据
  • 第二次握手为什么既有 SYN 又有 ACK
  • 某个报文段丢失会发生什么

就容易不会了。

本质上,三次握手不是背“哪三个包”,而是背“双方各自要完成什么状态确认”。

所以一旦理解为:

  • 客户端发起同步自己的初始序号
  • 服务器确认客户端并同步自己的初始序号
  • 客户端确认服务器的初始序号

很多变形题就顺了。

也就是说,握手题不要只记“图”,更要记“每一步各自在确认什么”。


二十、把题目里的“报文段”“确认号”“窗口”割裂开看

这是很多综合题做不出来的根本原因。

TCP 大题往往不是单独考某个点,而是把这些量放在一起:

  • 某报文段的 seq
  • 某报文段的数据长度
  • 收到后的 ack
  • 接收窗口大小
  • 还能继续发送多少
  • 下一次发送的 seq 应该是多少

如果复习时把这些内容孤立背诵,做题时就会觉得信息太多、太乱。

其实这些信息之间的关系非常固定:

seq 决定本段从哪开始。
数据长度 决定本段发到哪。
ack 决定对方确认到了哪。
window 决定还能向前开多宽。
于是就能判断下一段从哪发、还能发多少。

所以 TCP 综合题真正的核心不是“记住很多知识点”,而是把几个量的关系连起来看。


最后压缩成一版“高频坑点速记清单”

如果考前只想快速扫一遍,下面这一版最适合直接过脑子。

TCP 面向字节流,不保留消息边界;UDP 面向报文,保留消息边界。
TCP 的 seq 按字节编号,不按报文段编号。
TCP 的 ack 表示“期望收到的下一个字节编号”。
SYN 占 1 个序号,FIN 占 1 个序号,纯 ACK 不占序号。
TCP 首部中的窗口字段是接收方通告窗口,不是发送方自报发送能力。
发送窗口上限取 min(rwnd, cwnd)
当前还能发送的数据量,要再减去已发送未确认部分。
ack 决定左边界,window 决定宽度。
MSS 只指 TCP 数据部分最大长度,不含 TCP/IP 首部。
MSS 和 MTU 不是一回事,前者是传输层概念,后者是链路层概念。
三次握手的本质是双方确认彼此收发能力并同步初始序号。
四次挥手通常是因为 TCP 全双工,两个方向要分别关闭。
TIME-WAIT 的作用是保证最后 ACK 可重发,以及防旧报文干扰新连接。
TCP 可靠不等于永不丢包,而是通过协议机制保证最终正确交付。
TCP 与滑动窗口协议相似,但不能简单等同于 GBN。
序号绕回题一定先统一单位,按字节编号、按字节速率计算。

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇