📄 一句话概括
收到 FIN 就回 ACK 并通知应用(read 返回 0);应用 close 再回 FIN、收 ACK——服务器与客户端互为镜像,四次挥手不分主客。
📝 本节和前面几节的关系
数据收发讲完;本篇看收尾——TCP 的断开在服务器侧的样子。
一、服务器侧的挥手
收到 FIN -> 回 ACK -> 通知应用(read 返回 0); 应用处理完自己的尾巴调用 close -> 回 FIN -> 收 ACK。
二、等待期照旧
最后一个 ACK 之后仍有等待期(防迟到的旧包串门), 然后套接字才删除——与 2.4.2 完全一致。
三、动手 Demo:断开包的处理
服务器侧的四次挥手:
for s in ['收到 FIN -> 回 ACK -> 通知应用(read 返回 0)',
应用 close -> 回 FIN -> 收 ACK',
-> 等待期(防旧包串门)-> 套接字删除']:
print(s)
实跑输出:
--------------------------------------------------------------------
断开包的处理
--------------------------------------------------------------------
服务器侧的四次挥手:
收到 FIN -> 回 ACK -> 通知应用(read 返回 0)
应用 close -> 回 FIN -> 收 ACK
-> 等待期(防旧包串门)-> 套接字删除
与 2.4.1~2.4.2 的流程互相印证——
挥手从来都是两个人的事。
Web 场景通常是服务器先说完(响应发完), 于是常常是服务器先 FIN——谁先说完谁先关。
30 秒实验
- 默写四次挥手的完整时序。
- 解释为什么 read 返回 0 是断开信号。
- 复习 2.4.2:等待期防的是什么。
常见误区
- 以为断开只有一次挥手——四次,双方各表心意。
- 以为收完 ACK 立刻删套接字——还有等待期。
自测三问(点开对答案)
1. 收到 FIN 先做什么? —— 回 ACK 并通知应用。 2. 应用怎么知道断了? —— read 返回 0。 3. 等待期防什么? —— 迟到的旧包串进新连接。- ☐ 下一节(6.3.1 将请求的 URI 转换为实际的文件名)
相关笔记
- 数据发送完毕后断开连接 — 客户端侧的挥手
- 将请求的 URI 转换为实际的文件名 — 数据交给应用之后
- 🔌 网络是怎样连接的 · 索引