计网 01|TCP 三次握手、四次挥手到底为什么?seq/ack 手算 + 2MSL 讲透(17 年考了 16 次)
第一次做 2016 年那道运输层大题我盯着「写出释放连接过程中 A、B 的状态变化」愣了十分钟。三次握手、四次挥手这八个字我从大二就背得滚瓜烂熟。可一到要动笔把每条报文的 seq、ack、状态一步步写出来全乱套了。后来才想明白差在哪背的结论是「发了三个包」题要的是「每个包在数哪个字节、对方收到后进了哪个状态」。这两件事之间隔着一次真正的推导。这篇就把那次推导补上。它属于 408 里最值得死磕的地方——公开考频统计2009–2025里TCP 连接管理考了16 次跟子网划分并列第一其中还有 3 次是大题2012、2016、2023。〇、先花两分钟TCP 的「连接」到底是什么先说清三件事后面推报文才不会晕。第一所谓「连接」不是一条真的线。TCP 建立连接时双方各自在内存里建一份记录叫TCB传输控制块上面写着对方的 IP、端口、我发到第几个字节了、还能收多少——「建立连接」就是双方互相确认这份记录、并对齐初始序号。没有什么物理线路被接通。类比打电话拨通之后要问「喂你能听到我吗」「能你能听到我吗」「能」——三句话确认的是双向都能收发而不是单向。记住这个直觉下面「为什么是 3 次」就好懂了。第二seq和ack数的到底是什么。TCP 是面向字节流的——它不按「第几个包」编号而是按字节编号字段含义一句话记法seq本报文段数据的第一个字节在整个字节流里的序号我这一段从第几号字节开始ack期望对方下一个发来的字节序号第ack号之前我全收到了ack 1001的意思是「1 到 1000 我都收到了下次请从 1001 开始发」不是「我收到了第 1001 号」。第三也是最关键的一条握手和挥手的报文段不携带数据但SYN和FIN各要「消耗」1 个序号。这句话是几乎所有计算题的钥匙——为什么握手第二次要回ack x1就是因为第一次的SYN虽然没带数据却占了x这一个序号。图示三次握手与四次挥手完整时序图含每步的 seq/ack、双方状态变化下方是「为什么是 3 次 / 4 次 / 2MSL」三条原因一、三次握手三个报文段各干了什么按上图从上往下看三条报文依次是次序方向报文内容发送方状态变化接收方状态变化①A → BSYN1, seqxCLOSED →SYN-SENTLISTEN →SYN-RCVD②B → ASYN1, ACK1, seqy, ackx1SYN-SENT →ESTABLISHEDSYN-RCVD不变③A → BACK1, seqx1, acky1ESTABLISHED不变SYN-RCVD →ESTABLISHED逐条拆开看第①次A 主动打开发SYN1, seqxx是 A 自己选的初始序号。这个SYN报文段不携带数据但消耗 1 个序号——所以下一次 A 再发数据时序号从x1起。第②次B 被动打开回SYN1, ACK1, seqy, ackx1。注意这里一个报文段干了两件事ACK1确认收到 A 的SYN所以ack x1SYN1是 B 也要同步自己的初始序号y。它同样不携带数据同样消耗 1 个序号。第③次A 回ACK1, seqx1, acky1。这次是纯ACK可以携带数据如果不携带数据则不消耗序号下一个数据报文段的序号仍然是x1。顺手澄清一个常见误解第②次不是「先回 ACK再发 SYN」两个包——教材的标准写法是一个报文段同时置SYN1和ACK1。确实存在拆成两个包的分法效果等价但那不是考试的默认写法。为什么是三次不是两次这是大题常问的一句标准答案要看教材口径防止「已失效的连接请求报文段」突然又传到服务端造成资源浪费。具体讲A 发出的第一个连接请求SYN在某个节点滞留了很久延误到这次连接释放之后才到达 B。如果只有两次握手B 一收到就认为新连接建立、回个确认就开始等数据而 A 根本没发过这个请求不会发数据——B 的连接资源就白白占着。三次握手里 B 收不到 A 的第三次确认就知道 A 没有建连意图资源自然释放。另外还有一个更好懂的角度理解用、答题时别当主答案两次握手只能确认单向可达。第①次证明「A 能发到 B」第②次证明「B 能发到 A」缺第③次B 不知道自己的SYN有没有被 A 收到。二、三次握手里最容易丢分的三个细节这三个点年年有人栽全在一句话能说清的地方。①SYN消耗序号纯ACK不消耗。第①、②次的seq分别是x、y第③次 A 的seq就变成了x1——这多出来的 1就是第①次的SYN占掉的。算序号的时候漏掉这一步后面全错。② 第三次握手可以携带数据。因为此时 A 已经进入ESTABLISHED可以顺带把应用数据捎上数据到了 BB 也已ESTABLISHED能正常接收。前两次都不能带数据SYN报文段不携带数据是规定。③ack永远是「下一个期望的字节」不是「已收到的最后一个字节」。B 收到seqx的SYN回的必须是ackx1不是ackx。三、四次挥手为什么必须是四次挥手就是上面那张图的下半部分。同样是主动方 A 先动四条报文次序方向报文内容主动方 A被动方 B①A → BFIN1, sequESTABLISHED →FIN-WAIT-1ESTABLISHED →CLOSE-WAIT②B → AACK1, seqv, acku1FIN-WAIT-1 →FIN-WAIT-2CLOSE-WAIT不变③B → AFIN1, ACK1, seqw, acku1FIN-WAIT-2不变CLOSE-WAIT →LAST-ACK④A → BACK1, sequ1, ackw1→TIME-WAIT等 2MSL 后 CLOSEDLAST-ACK →CLOSED其中u是 A 之前已发送数据的最后一字节序号 1v是 B 已发数据末字节 1w是 B 在半关闭期间可能又发了数据之后的末字节 1。为什么建连 3 次、释连却要 4 次因为TCP 是全双工两个方向是两条独立的通道关闭必须各自关各自的。A 发FIN只说明「A 不再发数据了」但B 可能还有数据要发所以 B 不能把「确认」和「我也关了」合并成一个包发——只能先回一个ACK第②次等自己数据也发完了再单独发FIN第③次。而握手能合并是因为握手时双方都还没有数据要发B 的「确认」和「同步我的序号」可以塞进同一个报文段就是第②次那个SYN1, ACK1。第②次之后有一段「半关闭」状态CLOSE-WAITA→B 方向已经关了但 B→A 方向还开着B 仍然可以继续把数据发给 A。这是挥手里唯一一个「半边关着、半边开着」的阶段也是判断「谁在主动关闭」的关键。四、TIME_WAIT 与 2MSL为什么等的是 2 个 MSL最后一个报文段发完A 进入TIME-WAIT要等2MSL才真正CLOSED而 B 收到第④次ACK就立刻CLOSED了——被动关闭方反而先结束这一点常考。MSL 最长报文段寿命Maximum Segment LifetimeRFC 793 建议取2 分钟。所以按考试口径TIME-WAIT持续2MSL 4 分钟。真实系统上各家的实现取值不同不作为计算依据考试一律按 RFC 793 口径。为什么要等 2MSL而不是 1MSL 或干脆不等两个原因答大题时两个都要写保证最后一个ACK能到达 B。如果第④次ACK在路上丢了B 会超时重传FINACKA 还在TIME-WAIT里等着就能收到这个重传、重发一次ACK并且重置 2MSL 计时器——这样双方才能都正常CLOSED。要是 A 发完ACK立刻关闭B 等不到确认会一直重传最后只能异常断开。防止旧连接的报文段混入新连接。等满 2MSL本次连接期间产生的所有报文段都从网络上消失了下一个新连接不会收到上一个连接的残留SYN或数据段。顺带记一个副作用正因为第 1 条里可能反复重传ACK、每次都重置计时器实际TIME-WAIT的持续时间可能是 2MSL 的若干倍——2016 年大题问的就是这个「最短 / 最长」区间看到「重置计时器」四个字就要反应过来。五、11 个连接状态怎么记不用死背按「谁主动、走到哪一步」分组记状态谁在什么时刻进入CLOSED起点TIME-WAIT满 2MSL 后回到这里LISTEN服务器被动打开创建 TCB 等请求SYN-SENT客户发完第①次SYNSYN-RCVD服务器收SYN并回SYNACKESTABLISHED三次握手完成FIN-WAIT-1/FIN-WAIT-2主动方发FIN后 / 收到对方ACK后CLOSE-WAIT被动方收到FIN并回ACK后半关闭LAST-ACK被动方发出自己的FIN后TIME-WAIT主动方发出最后一个ACK后等 2MSLCLOSING双方几乎同时发FIN少见知道有这状态即可记忆主线CLOSED → SYN-SENT → ESTABLISHED → FIN-WAIT-1 → FIN-WAIT-2 → TIME-WAIT → CLOSED客户侧服务器侧是CLOSED → LISTEN → SYN-RCVD → ESTABLISHED → CLOSE-WAIT → LAST-ACK → CLOSED。六、17 年真题都考在哪数据口径以下为公开考频统计2009–2025整理的年份与题号用于判断「值不值得投入时间」不作为押题依据个别题号可能有 1–2 位偏差仅供参考。考点题型与频次真题年份题号TCP 连接管理建连 / 释连 / 状态机小题 13 次 大题 3 次 16 次2009(38)、2010(39)、2011(39,40)、2012(47)、2013(39)、2015(39)、2016(41)、2017(39)、2019(38,39)、2020(39)、2021(38,40)、2022(39)、2023(47)TCP 流量控制与拥塞控制小题 4 次 大题 1 次2009(39)、2014(38)、2020(38)、2022(38)、2023(47)TCP 报文段首部字段小题 2 次 大题 1 次2011(40)、2012(47)、2021(39)UDP 协议 / 数据报小题 3 次2014(39)、2018(39)、2021(39)两道必须完整做一遍的大题2016 年第 41 题一题四问——TCP 报文标志位、拥塞控制窗口变化、释放连接的状态时间计算、报文段序号的含义。这一道把本章主干全覆盖了。2023 年第 47 题TCP 连接建立的标志位 拥塞控制窗口变化。一个规律2019、2021、2023 连着几年都是「小题考状态、大题考推算」。也就是说光能说出「三次握手四次挥手」这八个字一分也拿不到——必须能自己把seq、ack、状态推一遍。七、易错点清单做题前扫一眼全是真题里挖过的坑易错点正确说法把ack当成「已收到的最后一个字节」ack期望的下一个字节序号所以是x1不是x以为握手三个包都不带数据第三次的ACK可以携带数据不带数据则不消耗序号漏掉SYN/FIN各消耗 1 个序号这是所有序号计算题的第一步漏了后面全错把TIME-WAIT时长写成MSL是2MSLRFC 793 口径 4 分钟只答 2MSL 的一个原因两个都要答保证最后 ACK 到达 防止旧连接报文段混入认为主动关闭方先结束被动方先CLOSED主动方还要在TIME-WAIT里等 2MSL把CLOSE-WAIT和LAST-ACK弄反CLOSE-WAIT是收到FIN后半关闭LAST-ACK是自己发完FIN后把TIME-WAIT时长当成固定值若最后ACK丢失触发重传计时器会重置时长可能成倍增加速查表文末收藏版# ---- 三次握手记序号SYN 各占 1 号---- A: CLOSED → ① SYN1, seqx → SYN-SENT B: LISTEN → ② SYN1, ACK1, seqy, ackx1 → SYN-RCVD A: (SYN-SENT) → ③ ACK1, seqx1, acky1 → ESTABLISHED B: 收到 ③ → ESTABLISHED # 第③次可携带数据不带数据则不消耗序号 ​ # ---- 四次挥手记序号FIN 也占 1 号---- A: ① FIN1, sequ → FIN-WAIT-1 B: CLOSE-WAIT半关闭② ACK1, seqv, acku1 A: 收到 ② → FIN-WAIT-2 B: 无数据可发时 ③ FIN1, ACK1, seqw, acku1 → LAST-ACK A: ④ ACK1, sequ1, ackw1 → TIME-WAIT等 2MSL→ CLOSED B: 收到 ④ → CLOSED先结束 ​ # ---- 关键结论 ---- # 建连 3 次防止已失效的连接请求报文段占用服务端资源 # 释连 4 次全双工两个方向必须各自独立关闭B 可能还有数据要发 # TIME-WAIT 2MSLRFC 793 口径 4 分钟 # 原因①保证最后 ACK 送达丢失则 B 重传 FINA 重发 ACK 并重置计时器 # 原因②防止旧连接报文段混入新连接 # 状态主线客户CLOSED→SYN-SENT→ESTABLISHED→FIN-WAIT-1→FIN-WAIT-2→TIME-WAIT→CLOSED # 状态主线服务器CLOSED→LISTEN→SYN-RCVD→ESTABLISHED→CLOSE-WAIT→LAST-ACK→CLOSED # 被动关闭方先 CLOSED主动关闭方多等 2MSL一句话总结三次握手的重点不是「三个包」是SYN占 1 个序号、ack指的是下一个字节四次挥手的重点不是「四个包」是全双工要单向单向地关。把这两个「为什么」说清这一章的分数就稳了。本文依据知识点谢希仁《计算机网络第 8 版》第 5 章 5.9 节「TCP 的运输连接管理」考频与真题年份题号公开考频统计2009–2025整理口径为「真题年份(题号)」仅用于排优先级不作为押题依据引用真题408 真题 2016 年第 41 题、2023 年第 47 题、2012 年第 47 题时间与状态取值MSL 取 RFC 793 建议值 2 分钟真实系统实现差异不参与考试计算

相关新闻

RGB-IR双模态目标检测:输入级融合原理与工程实践

RGB-IR双模态目标检测:输入级融合原理与工程实践

做双模态目标检测的这几个月,我最大的感受是:很多人对“输入级融合”有偏见,觉得它就是简单拼一下通道,没技术含量。实际跑下来恰恰相反,输入级融合在工程量、性价比和论文可解释性上是被低估的方案。这篇文章我就把 R…

2026/10/15 15:00:43 阅读更多 →
易语言数据库添加记录与写字段:两种写入方式一次讲透

易语言数据库添加记录与写字段:两种写入方式一次讲透

做易语言教程相关的技术分享时,我发现"数据库写和添加记录"是新手咨询频率最高的问题之一。很多朋友已经把窗口、编辑框、按钮一个个摆得整整齐齐,程序也能跑起来了,但一到了数据保存环节就卡壳:是该用自带数据库还是SQ…

2026/10/15 15:00:43 阅读更多 →
openrig:用Node.js和tmux搭建可复现的AI编程工作台

openrig:用Node.js和tmux搭建可复现的AI编程工作台

1. 从"openrig"这个名字说起:它到底想解决什么问题第一次看到"openrig"这个词,我脑子里蹦出来的不是某个具体产品,而是一种"开放式工作台"的直觉。rig在英文里本意是"装配、搭建一套设备"&#xff0…

2026/10/15 14:59:42 阅读更多 →

最新新闻

酒店管理系统PHP源码:从课设到生产部署的完整改造指南

酒店管理系统PHP源码:从课设到生产部署的完整改造指南

简介:一套面向酒店日常运营的信息化管理PHP源码,适合PHP开发者、酒店信息技术人员以及Web应用方向学习者参考。系统基于PHP与Access数据库构建,按接待、餐饮、采购、经理四个核心部门划分业务模块,覆盖客户预订、入住退房、菜单点…

2026/10/15 15:43:46 阅读更多 →
HarmonyOS 7文搜图 + 3DGS:文字描述检索并加载空间资产

HarmonyOS 7文搜图 + 3DGS:文字描述检索并加载空间资产

文搜图 3DGS:文字描述检索并加载空间资产 商品库里有 3000 多个 3DGS 资产,用户在搜索框敲一句"红色运动鞋",期望不是看到一张平面缩略图,而是直接把对应的高斯点模型加载进空间场景里转着看。这件事拆开看是两段能力拼…

2026/10/15 15:43:46 阅读更多 →
Delphi数据库组件源码跨版本编译与实战指南

Delphi数据库组件源码跨版本编译与实战指南

简介:Absolute Database v7.93 源代码包面向 Delphi 开发者,尤其是需要在 Delphi 4 至 11(含 Delphi 11 Alexandria)环境中集成嵌入式关系型数据库的工程师。它提供完整的数据库引擎实现,涵盖事务处理、内存与缓存优化…

2026/10/15 15:43:46 阅读更多 →
HarmonyOS 7重建结果缓存策略:LRU 与按场景分组

HarmonyOS 7重建结果缓存策略:LRU 与按场景分组

重建结果缓存策略:LRU 与按场景分组 商品列表有 50 个 3DGS 场景,用户翻来翻去看。第一次进商品详情要重建(或下载预重建结果),耗时 600-1200 ms。第二次进同一个商品如果还要重建,用户会觉得"我都看过…

2026/10/15 15:43:46 阅读更多 →
老鼠走迷宫课设:用栈与队列吃透DFS和BFS

老鼠走迷宫课设:用栈与队列吃透DFS和BFS

简介:一份面向数据结构课程设计场景的C迷宫求解项目,适合计算机相关专业学生完成课设或练习图、栈、DFS/BFS等算法时参考;项目把迷宫抽象为二维数组表示的图,用0/1标记通路与墙体,以老鼠走迷宫为线索,完整演…

2026/10/15 15:43:46 阅读更多 →
道路检测与整车控制:从解压到实车验证的完整落地链路

道路检测与整车控制:从解压到实车验证的完整落地链路

简介:这是一份面向自动驾驶与车辆工程方向学习者的C综合项目压缩包,围绕道路检测与整车控制两大主题,涵盖传感器数据处理、车道线/斑马线识别、控制策略等实现思路,适用于正在研究ADAS、车辆动力学或Visual Studio工程实践的开发者…

2026/10/15 15:42:41 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →