Skip to content

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

2026 大纲 五(三)2 TCP 连接管理。seq / ack 的逐报文推演、状态机、2MSL 的两个理由集中在本篇;首部字段的位数与选项容量见《TCP 协议基础》。

一、连接建立:为什么非要三次

"面向连接"的含义是两端各存一份对端状态。建立连接就是把这份状态建起来,教材列了三件要办的事:使每一方确知对方的存在;允许双方协商参数(最大窗口值、是否使用窗口扩大与时间戳选项、服务质量等);对传输实体资源分配(缓存大小、连接表中的项目)。

三个报文段依次是:① A→B SYN=1, seq=x(A 进 SYN-SENT);② B→A SYN=1, ACK=1, seq=y, ack=x+1(B 进 SYN-RCVD);③ A→B ACK=1, seq=x+1, ack=y+1(双方 ESTABLISHED)。

第一次握手 ACK=0:还没收到对方任何东西,确认号字段无意义;此后所有报文段 ACK 恒为 1。

谁能携带数据,是序号计算题的第一个入口SYN 报文段(前两次)不能携带数据,但各消耗一个序号第三次的 ACK 可以携带数据,若不携带则不消耗序号——下一个数据报文段的序号仍然是 x+1

为什么是三次,不是两次

核心是教材那句:防止已失效的连接请求报文段突然又传送到了 B,因而产生错误。

只有两次握手时,B 一发出确认就认定连接已建立、分配缓存与连接表项空等,而 A 根本没要求建连——资源白白浪费。第三次握手让故障消失:B 发出确认后并不立即进入 ESTABLISHED,而是等 A 的再次确认;A 不回,B 就知道 A 并没有要求建立连接。

已失效的连接请求到底怎么坑到 B(想把这条故障链逐步走一遍时展开)
  1. A 发出第一个连接请求报文段,但它在某个网络节点长时间滞留了;
  2. A 迟迟收不到确认,于是超时重传一个新的连接请求,这次一切正常,双方建立连接、传完数据、释放连接;
  3. 此时那个滞留的旧请求终于到达了 B
  4. B 收到这个"已失效的连接请求报文段",误以为 A 又要建立新连接,于是发回确认,同意建立;
  5. 若只有两次握手,B 一发出确认就认为新连接已经建立,并分配缓存、建连接表项,一直等 A 发数据;
  6. 但 A 并没有发出建立连接的请求,不会理睬 B 的确认,也不会向 B 发送数据。B 的资源就这样白白浪费了。

换一个角度:三次握手让双方都确认了对方的发送能力与接收能力。

报文A 由此确认B 由此确认
① A→BA 的发送能力正常、B 自己的接收能力正常
② B→AB 的收发能力都正常、A 自己的收发能力都正常
③ A→BA 的接收能力正常、B 自己的发送能力正常

两次握手到第 ② 步就停了,此时 B 完全不知道自己发出去的报文 A 有没有收到——它的发送能力和 A 的接收能力都还没被验证过。第三次握手补上的正是这一格。

资源分配的时机决定了 SYN 洪泛能成立

服务器在第二步就分配了资源、建立半开连接(SYN-RCVD),而第三个 ACK 是否到来完全取决于对方。攻击者伪造大量不同源 IP 的 SYN,服务器为每个请求分配资源并回 SYN+ACK,第三次握手却永远不到,半开连接耗尽资源——这就是 SYN 洪泛

SYN Cookie 的思路:收到 SYN 时不分配资源,把状态编码进 SYN+ACK 的初始序号里,只有收到能反解出这份状态的第三次握手才真正分配。它把"要不要付出内存"推迟到第三步——正好推到了攻击者付不起代价的位置。

二、连接释放:为什么要四次

四个报文段是:① A→B FIN=1, seq=u(A 进 FIN-WAIT-1);② B→A ACK=1, seq=v, ack=u+1(B 进 CLOSE-WAIT 并通知高层应用进程,A 进 FIN-WAIT-2);③ B→A FIN=1, ACK=1, seq=w, ack=u+1(B 进 LAST-ACK);④ A→B ACK=1, seq=u+1, ack=w+1(A 进 TIME-WAIT)。

建连 3 次、拆连 4 次的源头只有一处:握手第二步 B 的"我确认收到"与"我也要建连"同时成立,可以合并;挥手第二步只有"我确认收到"立即成立,"我也发完了"未必——B 可能还有数据要发,强行等着会让 A 超时重传 FIN。反过来说,若 B 恰好也没数据要发,挥手可以退化成三报文

第三次挥手的 seq 不一定等于第二次,判据是B 在半关闭期间有没有再发数据:没发则 w=v,发过则 w>v

半关闭指的是:第二次挥手后 A→B 方向已关,B→A 方向仍然有效——B 可继续发,A 必须继续收并发确认。所以处在 FIN-WAIT-2 的 A 照样能收数据。这有实际用途:把文件送进管道再等结果的程序(如 sort 客户端),可以数据发完就关掉发送方向告诉对方"输入到此为止",同时保持接收方向等结果。

TIME-WAIT 与 2MSL

TIME-WAIT 是主动关闭方的状态,被动方反而先结束——B 收到最后那个 ACK 就撤销 TCB、立即 CLOSED,比 A 早整整 2MSL。

2MSL 有两个理由,都要能说出来。

其一,保证最后一个 ACK 能到达 B。 这个 ACK 若丢了,处在 LAST-ACK 的 B 会超时重传 FIN+ACK;A 还在 2MSL 内就能收到,于是重传确认、重启计时器。A 若发完就走,B 就无法按正常步骤进入 CLOSED。

其二,使本连接期间产生的所有报文段都从网络中消失,防止旧报文串进后来那条四元组相同的新连接。

为什么恰好是 2 倍:最后那个 ACK 在网络中存活至多 1 个 MSL,加上对方因此重传的 FIN+ACK 走回 A 至多 1 个 MSL。

TIME-WAIT 会把源端口占住整整 2MSL,所以同一对端的短连接建立速率存在上限(可用端口数 ÷ 2MSL)。由此可知:大量 TIME-WAIT 不是故障,而是协议的正确行为

顺带一处计数陷阱:数短暂端口区间别漏那个 +1。端口号是闭区间上的整数,[a,b] 里有 ba+1 个——可用短暂端口 49152~65535 共 6553549152+1=16384 个,不是 16383。

FIN 与 RST 不是一回事:FIN 是正常关闭(我这个方向发完了,对方还可以继续发);RST 是异常终止(连接中出现严重差错必须释放后重建,也用来拒绝非法报文段或拒绝打开连接),收到 RST 的一方直接关闭、不必发确认

三、序号推演的三条规则

这三条是本章所有序号题的全部依据:

① 确认号 = 对方报文段的 seq + 该报文段消耗的序号数。② SYN 与 FIN 各消耗一个序号(即使不携带数据)。 ③ 不携带数据的纯 ACK 不消耗序号——发完之后自己的 seq 不变。

还有一条容易搞反的措辞要单独按住:报文段的 seq 是它占用的第一个序号,不是"占完之后的下一个"。 "FIN 消耗一个序号"说的是它占掉了自己那个 seq,它自身的 seq 不 +1;SYN 同理。

握手 + 双向数据 + 挥手的 seq/ack 完整推演(第一次做推演题、或想验一遍三条规则时展开)

设客户 A 的初始序号 x=1200、服务器 B 的初始序号 y=5000;连接建立后 A 先发 300 字节,B 确认后发 500 字节,A 确认后主动关闭(B 此后无新数据)。

三报文握手:

#方向标志位seqack依据
1A→BSYN=11200ACK=0,确认号无意义
2B→ASYN=1, ACK=150001201A 的 SYN 消耗 1 个序号 → 1200+1
3A→BACK=112015001B 的 SYN 消耗 1 个序号 → 5000+1;本段不带数据,不消耗序号

第 3 步的 seq 是 1201 而不是 1200:A 的 SYN 已经"用掉"了序号 1200,下一个可用的字节编号就是 1201。

A 发 300 字节:

#方向标志位seqack长度依据
4A→BACK=112015001300覆盖字节 1201~1500。第 3 步不消耗序号,所以 seq 仍是 1201
5B→AACK=15001150101201+300=1501。B 还没发过数据,seq 仍是 5001

B 发 500 字节:

#方向标志位seqack长度依据
6B→AACK=150011501500覆盖字节 5001~5500。第 5 步是纯 ACK,不消耗序号
7A→BACK=11501550105001+500=5501

四报文挥手:

#方向标志位seqack依据
8A→BFIN=1, ACK=115015501A 发完 300 字节后下一个可用序号就是 1501
9B→AACK=155011502A 的 FIN 消耗 1 个序号 → 1501+1
10B→AFIN=1, ACK=155011502B 半关闭期间无新数据,所以 seq 仍是 5501
11A→BACK=115025502B 的 FIN 消耗 1 个序号 → 5501+1

三条快速自检:

  • A 一共消耗的序号 = SYN 1 + 数据 300 + FIN 1 = 302,末状态 seq = 1200+302=1502 ✓;
  • B 一共消耗的序号 = SYN 1 + 数据 500 + FIN 1 = 502,末状态 seq = 5000+502=5502 ✓(体现在第 11 步的 ack 上);
  • 每一个 ack 都恰好等于对方接下来要用的那个 seq(第 5 行的 ack=1501 正是第 8 行 A 的 seq=1501)——累积确认语义的直接体现,也是最快的横向对账法。

第 10 行是全表最容易错的一格。很多人会写成 5502,理由是"B 的 FIN 也要消耗序号"。消耗序号说的是"这个报文段占掉了序号 5501,下一个才是 5502",不是"这个报文段的 seq 要 +1"。

交互可视化

加载可视化中...
加载可视化中...

四、四种计时器

计时器谁启动何时启动到期做什么防的是什么
重传计时器(RTO)发送方发出报文段时重传该报文段数据或确认在路上丢了
持续计时器收到零窗口通知的一方收到 rwnd=0发零窗口探测报文段(1 字节)窗口更新通知丢失造成的死锁
保活计时器服务器每收到一次客户数据即重置(通常 2 小时发探测报文段,此后每隔 75 秒一次,连发 10 个无响应就关连接对端主机崩溃留下的僵尸连接
时间等待计时器(2MSL)主动关闭方发出最后一个 ACK 时进入 CLOSED最后一个 ACK 丢失 + 旧报文串进新连接

取值一律由实现决定,教材给出确切数字的只有保活这一组,由它可算出最长挂起 2 小时+10×75 =2 小时 12.5 分钟

真正要能答的是最后一列:每个计时器各自在防哪一种"对方不说话"。 其中持续与保活最容易混——持续面对的是"对方活得好好的,只是通告了零窗口而'我又腾出空间了'的通知丢了",探测问的是"窗口现在多大",防的是僵局保活面对的是"对方可能已经不存在了",探测问的是"你还在不在",防的是僵尸连接

五、有限状态机

线索是名字本身:带 WAIT 的一定在等某个东西,等什么直接看它的下一个状态——FIN-WAIT-1 等 ACK、FIN-WAIT-2 等 FIN、TIME-WAIT 等时间、CLOSE-WAIT 等本端应用调用关闭、LAST-ACK 等最后那个 ACK。再按主动方 / 被动方分两列排时间序,基本不用背。

CLOSE-WAIT 是这组里唯一的例外,值得单独记:其余带 WAIT 的状态都在等对方的报文,只有它在等本端程序调用关闭。所以生产环境里大量 CLOSE-WAIT 堆积,说明的是本端程序忘了关连接,不是网络的问题

同时打开与同时关闭是状态机完整性所要求的分支:同时打开时两端都从 SYN-SENT 收到对方的 SYN 转入 SYN-RCVD,四个报文段建成一条连接(四元组相同);同时关闭时两端都走 FIN-WAIT-1 → CLOSING → TIME-WAIT → CLOSED,都要等 2MSL

十一个状态的含义与主动方 / 被动方分列(想系统过一遍状态名时展开)
阶段主动方(客户 / 主动关闭方)被动方(服务器 / 被动关闭方)
建连接SYN-SENT(发了 SYN 在等LISTEN(在听)→ SYN-RCVD(收到 SYN 了在等 ACK
传数据ESTABLISHEDESTABLISHED
拆连接FIN-WAIT-1(发了 FIN 在等)→ FIN-WAIT-2(等到 ACK 了,还在等对方的 FIN)→ TIME-WAIT(都完了,等 2MSLCLOSE-WAIT(收到 FIN 了,等本端应用关)→ LAST-ACK(发了 FIN,等最后一个 ACK
特例CLOSING(同时关闭:我发了 FIN,等到的却是对方的 FIN)
状态含义在等什么
CLOSED初始 / 终止状态,无连接
LISTEN服务器等待连接请求对方的 SYN
SYN-SENT已发送 SYN对方的 SYN+ACK
SYN-RCVD已收到 SYN 并回了 SYN+ACK对方的 ACK(第三次握手)
ESTABLISHED连接已建立,正常传数据
FIN-WAIT-1主动关闭方已发 FIN对方的 ACK(或 FIN)
FIN-WAIT-2已收到对方的 ACK(半关闭)对方的 FIN
CLOSE-WAIT被动关闭方已回 ACK本端应用调用关闭
LAST-ACK被动关闭方已发 FIN最后一个 ACK
TIME-WAIT已发出最后一个 ACK2MSL 到期
CLOSING同时关闭时的中间态对方对我的 FIN 的 ACK

本节小结

  1. 握手三次、挥手四次的差别只有一个源头:握手第二步 B 的"确认"与"我也要建连"同时成立可以合并,挥手第二步"我也发完了"未必成立所以必须拆开。三次握手防的是已失效的连接请求让 B 单方面认定连接建立、分配资源空等;而"第二步就分配资源"正是 SYN 洪泛能成立的原因。
  2. 推演三规则:确认号 = 对方 seq + 该报文段消耗的序号数;SYN 与 FIN 各消耗一个序号;纯 ACK 不消耗。报文段自身的 seq 永远是它占用的第一个序号。自检:一端的末 seq = 初始序号 + (SYN 1 + 数据字节数 + FIN 1)。
  3. TIME-WAIT 属于主动关闭方,被动方先结束;2MSL 的两个理由是"保证最后一个 ACK 能到达"与"让本连接的残留报文全部过期",2 倍来自"ACK 存活 1 个 MSL + 对方重传走回 1 个 MSL"。主机崩溃时由保活计时器兜底;持续计时器防僵局、保活计时器防僵尸。

考点速记

这是传输层里真题最密的一篇,真题里被考过的形式可以归成五组,五组共用第三节那三条推演规则

A 组:握手报文段的序号该填什么。

cn-2011-39 给甲发出的 (SYN=1, seq=11220),问乙同意建连时可能回什么。答 C:(SYN=1, ACK=1, seq=11221, ack=11221)。判据两条:第二次握手必须 SYN=1 且 ACK=1(A、D 都写成 0,直接出局);确认号必须是 11220+1=11221(B 写成 11220,漏了"SYN 消耗一个序号")。至于 seq = 11221 只是乙自己挑的初始序号,取什么值都行——题干问的是"可能是",别在这个字段上纠结。

cn-2019-39 更直接:甲、乙的初始序号分别是 2018 和 2046,问第三次握手的确认序号。第三次握手是 A→B,它确认的是 B 的 SYN(seq = 2046),所以 ack =2046+1=2047,答 D这道题的四个选项正是 2018/2019/2046/2047 四种组合——选 2019 的是把方向搞反了(那是第二次握手的确认号),选 2046 的是漏了 +1。

cn-2026-47 的第 (1) 问同款:C 的初始序号 1000、Si 的 2000,问 C 收到的"SYN=1、ACK=1"那个段的确认序号。那是第二次握手,确认的是 C 的 SYN,ack =1000+1=1001

B 组:从序号反推发了多少数据。

cn-2020-39 是这组的模板:SYN 段序号 1000、FIN 段序号 5001,问甲已发送的应用层数据字节数。

SYN 占掉序号 1000,所以数据从 1001 开始FIN 的 seq 是它占用的第一个序号,说明最后一个数据字节是 5000。于是数据是 10015000,共 50001001+1=4000 字节,答 C

四个选项 3999/4000/4001/4002 精确覆盖四种算错方式:直接 50011000=4001(两头都没处理)、50011001+1=400150011000+1=4002……只有把"SYN 占一个""FIN 的 seq 是首个未用序号"两条同时用对才能落在 4000 上。

cn-2023-47 的第 (2) 问是同一套动作的综合题版:H 的初始序号 100 → 数据从 101 开始;上传 18000 B → 最后一字节 101+180001=18100FIN 段 seq = 18101 → 第二次挥手的 ACK 序号 = 18101+1=18102

cn-2026-47 的第 (3) 问再走一遍:C 初始序号 1000 → 数据 10013000(2000 B)→ FIN seq = 3001;Si 没发数据,序号始终停在 2001。C 收到的最后一个报文段是第三次挥手,其 seq = 2001、ack_seq = 3002、FIN = 1

C 组:挥手过程中的状态转换。

cn-2021-38 问:客户先发 FIN,收到服务器的 FIN 并回了 ACK 之后,客户处于什么状态。答 B:TIME_WAIT

按第五节那条线索走一遍就行:发 FIN → FIN_WAIT_1(等 ACK)→ 收到 ACK → FIN_WAIT_2(等对方的 FIN)→ 收到 FIN 并发出 ACK → TIME_WAIT(等 2MSL)。干扰项 CLOSE_WAIT 是被动关闭方的状态,它出现在收到 FIN 的那一端,客户是主动关闭方,永远走不到。

D 组:从某个时刻算到 CLOSED 要多久。这组最容易在"算谁"上翻车。

cn-2022-39:RTT = 50 ms、MSL = 800 ms,C 主动断开,问 C 和 S 分别进入 CLOSED 至少要多久。

分开算,而且两边的终点完全不同。C 这一侧:t=0 发 FIN,t=50 ms 收到 S 的 FIN(S 无数据时 ACK 与 FIN 可合并),发出最后的 ACK 进入 TIME-WAIT,再等 2MSL=1600 ms → 1650 ms。S 这一侧:t=25 ms 收到 FIN 并发出 ACK+FIN,t=75 ms 收到 C 的最后 ACK → 立即 CLOSED,75 ms。答 D

这道题把"TIME-WAIT 只属于主动关闭方"考成了一个数量级的差距——1650 对 75,谁记反了谁就选到 A 或 C。

cn-2024-38 把建连、传数据、拆连串成一条时间线:RTT = 10 ms、MSL = 30 s、MSS = 1000 B、报文 3000 B,问从请求建立连接起到 H 进入 CLOSED 的最少时间。

逐段算:t=0 发 SYN;t=10 ms 收到 SYN+ACK,发出第三次握手的 ACK 并携带第 1 段数据(慢开始,cwnd = 1 MSS);t=20 ms 收到确认,cwnd = 2,发出第 2、3 段——3000 B 至此发完t=30 ms 收到确认;H 随即发 FIN,t=40 ms 收到 FIN+ACK 并发出最后的 ACK,进入 TIME-WAIT;再等 2MSL=60 s。合计 60.04 s,答 D

选项里的 60.03 和 30.04 各错一处:前者少算了拆连的那 10 ms,后者把 2MSL 写成了 1 个 MSL。凡是问"到 CLOSED 为止",2MSL 就一定要算进去;凡是问被动方,就一定不算。

cn-2016-41 的第 (4) 问反过来问被动方:从 H3 请求断开起,S 释放该连接的最短时间。S 在收到 H3 的最后一个 ACK 时就 CLOSED——RTT/2(FIN 到 S)+ RTT/2(S 的 FIN 到 H3)+ RTT/2(H3 的 ACK 到 S)= 1.5×RTT=300 ms这一问不含 2MSL,因为 TIME-WAIT 在 H3 那一侧。

E 组:从十六进制 dump 里认标志位。

cn-2012-47(9 分)给出 5 个 IP 分组的前 40 字节,要求判断哪几个由 H 发送、哪几个完成了建连、哪几个被以太网填充。

三问三把尺子,都要先把偏移算准:以太网帧头 14 B 之后是 IP 首部(20 B,占字节 0~19),TCP 首部紧跟其后占字节 20~39

发送方看 IP 首部字节 12~15 的源 IP:c0 a8 00 08 = 192.168.0.8 就是 H 发的 → 1、3、4 号

建连看 TCP 标志位:0x02 = 仅 SYN(第一次握手)、0x12 = SYN+ACK(第二次)、0x10 = 仅 ACK(第三次)、0x18 = ACK+PSH(数据)→ 1、2、3 号完成三次握手

填充看 IP 总长度(字节 2~3):快速以太网最小载荷 46 B,总长 40 的 3、5 号要填充。这一问的边界是"填充由数据链路层自己加,IP 总长度字段不变"——接收方靠总长度就能剥掉填充。

第 (2) 问算 S 已收到的应用层字节数,用的是同一条累积确认语义:S 的 ACK 确认号数据起始序号=0x846B41D60x846B41C6=16 字节。

本篇练习区里还会出现六道题,它们的机制讲在别处:cn-2019-38 考快速重传、cn-2021-40 考发送窗口范围,讲在 TCP 可靠传输;cn-2015-39 考接收缓存填满后窗口怎么变,讲在 TCP 流量控制;cn-2017-39 与 cn-2025-38 考拥塞窗口的增长,讲在 TCP 拥塞控制拥塞控制逐轮推演;cn-2021-39 与 cn-2025-39 考 UDP 与 TCP 的开销对比,讲在 UDP 协议

易错SYN 与 FIN 各消耗一个序号,纯 ACK 不消耗。 这是全部序号题的唯一依据。

易错报文段的 seq 是它占用的第一个序号,不是"占完之后的下一个"。FIN 段的 seq 不 +1。

易错第二次握手必须 SYN=1 且 ACK=1,第一次握手 ACK=0,此后所有报文段 ACK 恒为 1。

易错算已发数据量时两头都要处理:数据从"初始序号 +1"开始,到"FIN 的 seq −1"结束。

易错TIME-WAIT 只属于主动关闭方,被动方收到最后 ACK 就立即 CLOSED。 问被动方时绝不算 2MSL。

易错2MSL 是 2 个 MSL,不是 1 个。 来历是"ACK 存活 1 个 MSL + 对方重传走回 1 个 MSL"。

易错CLOSE_WAIT 是被动关闭方的状态,主动关闭方永远走不到它。

易错CLOSE-WAIT 等的是本端应用调用关闭,其余带 WAIT 的状态都在等对方的报文。

易错第三次挥手的 seq 未必等于第二次——B 在半关闭期间发过数据就会变大。

易错第三次握手的 ACK 可以携带数据,所以"建连接的时间代价"算 1 个 RTT 而不是 1.5 个。

易错数端口区间要 +1。 49152~65535 共 16384 个。

教材出处
  • 谢希仁《计算机网络》(第 8 版)p247(5.9 TCP 的运输连接管理):连接建立要解决的三个问题原文——"(1) 要使每一方能够确知对方的存在。(2) 要允许双方协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等)。(3) 能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。"以及"主动发起连接建立的应用进程叫作客户,而被动等待连接建立的应用进程叫作服务器"。
  • 同书 p248(5.9.1 TCP 的连接建立):三报文握手的完整描述——"TCP 规定,SYN 报文段(即 SYN=1 的报文段)不能携带数据,但要消耗掉一个序号";"TCP 的标准规定,ACK 报文段可以携带数据。但如果不携带数据则不消耗序号,在这种情况下,下一个数据报文段的序号仍是 seq=x+1";以及两报文握手的故障场景与结论——"B 却以为新的运输连接已经建立了,并一直等待 A 发来数据。B 的许多资源就这样白白浪费了……采用三报文握手的办法,可以防止上述现象的发生"。同页还注明 B 发给 A 的报文段"也可拆成两个报文段"。
  • 同书 p249(5.9.2 TCP 的连接释放):四报文挥手的逐步描述——FIN 报文段"其序号 seq=u,它等于前面已传送过的数据的最后一个字节的序号加 1……TCP 规定,FIN 报文段即使不携带数据,它也消耗掉一个序号";B 收到后"即发出确认,确认号是 ack=u+1,而这个报文段自己的序号是 v,等于 B 前面已传送过的数据的最后一个字节的序号加 1。然后 B 就进入 CLOSE-WAIT(关闭等待)状态。TCP 服务器进程这时应通知高层应用进程"。
  • 同书 p250:2MSL 的两个理由原文——"第一,为了保证 A 发送的最后一个 ACK 报文段能够到达 B……B 会超时重传这个 FIN+ACK 报文段,而 A 就能在 2MSL 时间内收到这个重传的 FIN+ACK 报文段。接着 A 重传一次确认,重新启动 2MSL 计时器";"第二,防止上一节提到的'已失效的连接请求报文段'出现在本连接中。A 在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失"。同页还有"B 结束 TCP 连接的时间要比 A 早一些"。
  • 同书 p250(紧接 2MSL 之后):保活计时器原文——"除时间等待计时器外,TCP 还设有一个保活计时器(keepalive timer)。设想有这样的情况:客户已主动与服务器建立了 TCP 连接。但后来客户端的主机突然出故障。显然,服务器以后就不能再收到客户发来的数据。因此,应当有措施使服务器不要再白白等待下去。这就是使用保活计时器。服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置通常是两小时。若两小时没有收到客户的数据,服务器就发送一个探测报文段,以后则每隔 75 秒钟发送一次。若一连发送 10 个探测报文段后仍无客户的响应,服务器就认为客户端出了故障,接着就关闭这个连接"。
  • 同书 p251 图 5-30:TCP 的有限状态机,含同时打开与 CLOSING 分支,本篇状态图与状态表依此绘制。
  • 同书 p227(5.5 TCP 报文段的首部格式):RST 的定义——"当 RST=1 时,表明 TCP 连接中出现严重差错(如主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。将 RST 置为 1 还用来拒绝一个非法的报文段或拒绝打开一个连接";以及 SYN 的两种组合"当 SYN=1 而 ACK=0 时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使 SYN=1 和 ACK=1"。

相关知识

TCP 协议基础TCP 可靠传输TCP 流量控制

真题练习