🔌 第六章 请求到达Web服务器,响应返回浏览器
📄 一句话概括

收到 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 秒实验

  1. 默写四次挥手的完整时序。
  2. 解释为什么 read 返回 0 是断开信号。
  3. 复习 2.4.2:等待期防的是什么。

常见误区

  1. 以为断开只有一次挥手——四次,双方各表心意。
  2. 以为收完 ACK 立刻删套接字——还有等待期。
自测三问(点开对答案) 1. 收到 FIN 先做什么? —— 回 ACK 并通知应用。 2. 应用怎么知道断了? —— read 返回 0。 3. 等待期防什么? —— 迟到的旧包串进新连接。

相关笔记