FastAPI-01补.网络基础-TCP-HTTP与WebSocket

本系列:00 导读 · 01补 网络基础(本文) · 01 心智模型 · 02 路由与数据模型 · 02补 HTTP 方法对比 · 03 依赖注入与分层 · 04 中间件异常日志 · 05 异步后台与流式 · 06 鉴权与安全 · 07 测试与项目骨架 · 08 实战 HTTP↔MCP

行文:T1 原理篇(补充) | 本篇方法:费曼 + 双重编码 | 阅读时机:读 01 ASGI 前,或卡在「uvicorn 听端口 / 流式 vs WebSocket」时回看


0. 本文解决什么

读 FastAPI / uvicorn 时常遇到的空白:

  • host:port、TCP、「收 HTTP/WebSocket 流量」分别是什么?
  • HTTP 是不是「回一次响应就结束会话」?
  • WebSocket 长连接里,任务何时算结束?
  • HTTP 流式输出WebSocket 多次推送本质差在哪?

本篇只补网络与协议心智模型,不写业务路由;ASGI 合同见 01,流式代码见 05。


1. 寄信类比:host、port、uvicorn

host / port / TCP / HTTP 科普示意

概念 通俗含义 常见例子
主机(host) 哪台机器 / 哪栋楼 127.0.0.1(本机)、0.0.0.0(本机所有网卡对外)、域名
端口(port) 这栋楼里的哪个窗口 800080443
uvicorn 守在某个窗口的门房 uvicorn main:app --port 8000

一台机器上同时跑很多程序,不能都抢同一个入口,所以:

  • IP / 主机名 → 找到机器
  • 端口号(0~65535) → 找到这台机器上的某一个程序

uvicorn 的职责可以记成:

  1. 在指定 host:port 值班(听连接)
  2. 把进来的字节按 HTTP / WebSocket 规则拆开
  3. ASGI 约定调用你的 appscope / receive / send)——详见 01

段末注释TCP(Transmission Control Protocol,传输控制协议)在两台机器间建立可靠字节通道;HTTP(HyperText Transfer Protocol,超文本传输协议)是通道上「请求/响应」的说话方式;WebSocket 是可在同一连接上持续双向传消息的协议。后文沿用缩写。


2. TCP:先接通电话,再说话

访问 http://127.0.0.1:8000/ping 时,底层大致是:

  1. 127.0.0.1 找到机器(本机即自己)
  2. 8000 端口发起 TCP 连接(握手 ≈「电话接通」)
  3. 接通后传送的是字节流,本身不懂「这是网页还是聊天」
  4. 上层协议(HTTP / WebSocket)规定这些字节怎么解读

没有 TCP,就没有稳定通道;没有 HTTP/WebSocket,通道里只是无结构的字节。

1
2
3
4
5
6
7
8
9
10
浏览器 / 客户端
│ host + port
│ 建立 TCP
│ 按 HTTP 或 WebSocket 说话

uvicorn(守窗口)
│ 读字节 → 理解协议
│ 调 app(scope, receive, send)

FastAPI(路由与业务)

3. HTTP:结束的是「这一问一答」,不一定拆线

3.1 一次交互 vs 底下的连接

层级 发生什么
一次 HTTP 交互 客户端发一个请求 → 服务器回一个响应 → 这一次事务结束
底下的 TCP 不立刻断开(HTTP/1.1 默认 keep-alive),同一条线上还可再发下一个请求

更准确的说法:

HTTP 是 请求–响应 模型:一次请求对应一次完整响应,语义上「这一单办完」。
不是「响应一回去,整个网络会话必然结束」——电话可能还握着,只是这句对话说完了。

HTTP/2、HTTP/3 还可在一条连接上并行多个请求,但每个请求仍是「问完答完」。

3.2 和 uvicorn / FastAPI 的关系

  • 你写的每个 @app.get / @app.post,对应的是 一次 HTTP 请求–响应(在 ASGI 里常表现为一次 http scope 调用)。
  • 「会话」若指登录态,那是 Cookie / Token 等应用层概念,不是「TCP 必须一直连着」。

4. WebSocket:长连接聊天,结束点谁定?

握手成功后(常从 HTTP「升级」而来),进入 长连接:双方可随时推消息,没有「每个消息必须有一次响应就结束」的强制规则。

4.1 连接何时断(协议 / 运行时)

  • 任一方主动 close(正常关)
  • 网络中断、进程退出、代理掐断
  • 心跳(ping/pong)失败被判定掉线

4.2 业务任务何时算完(应用层)

协议不管「聊天任务做完没」。结束节点要你自己约定,例如:

结束方式 例子
显式结束消息 客户端发 {"type":"done"},服务端确认后双方 close
业务状态完成 生成结束,发完最后一个 chunk 再发 finish
超时 60s 无消息 → 服务端关闭
心跳失败 多次 ping 无 pong → 关闭
资源上限 达到最大时长 / 消息数后强制关

HTTP:协议帮你定义「一问一答完事」。
WebSocket:协议只保证「线还通着就能聊」;任务结束点 = 消息约定 / 状态机 + 最后 close


5. HTTP 流式 vs WebSocket:本质区别

表象都是「分多次把数据给客户端」,合同不同

HTTP 流式(含 SSE、StreamingResponse WebSocket
本质 一次请求 → 一次响应,响应体可边生成边写出 一条长连接上的双向消息通道,每条消息相对独立
像什么 点了菜,厨房分批上菜,这桌上完即结束 两人拿着对讲机,谁都能随时喊,直到挂断
典型方向 服务端 → 客户端(客户端先问一次) 双向
「多次」是什么 同一响应的 chunk / event 多条 独立 message
默认结束点 响应写完(生成器结束) 应用约定 + close
客户端中途插话 弱(断流或另开请求) 强(随时发消息)

5.1 交互模型对照

HTTP 流式:

1
2
3
客户端 ──一次 Request──► 服务器
客户端 ◄──一次 Response(可拆成很多 chunk)── 服务器
Response 写完 → 这一次 HTTP 事务结束
  • 流里的「多次」≠ 多次独立 HTTP 响应,而是同一个响应体的持续写出
  • 代码形态见 05 流式响应

WebSocket:

1
2
3
握手之后:
客户端 ◄──► 服务器 (任意次、双向、独立消息)
直到某方 close

5.2 怎么选

场景 更合适
LLM token、日志尾随、进度条、只推不互动 HTTP 流式 / SSE
双向实时、协同、客户端也要随时发指令 WebSocket

段末注释SSE(Server-Sent Events,服务器发送事件)是服务端向浏览器单向推送文本事件流的 HTTP 机制;规范上偏单向,实现上常挂在 text/event-stream


6. 和本系列其它篇的衔接

读完本篇应能… 下一站
解释 uvicorn 为何要 host:port 01 ASGI 与请求生命周期
区分「HTTP 事务结束」与「TCP 拆线」 01、日常调试 keep-alive
说明流式 ≠ WebSocket 05 异步与流式
知道长连接结束要自己约定 05 / 实战里的推送设计

7. 合书自测

  1. 用寄信类比说出 host、port、TCP、HTTP 各像什么。
  2. 「HTTP 回完响应」是否等于「TCP 一定断开」?为什么?
  3. WebSocket 上「业务做完」和「连接关闭」分别由谁决定?
  4. 一句话区分 HTTP 流式WebSocket 多次消息

8. 闪卡候选

正面 背面
port 是什么? 同一主机上区分不同服务的「窗口号」
uvicorn 听端口之后做什么? 解析 HTTP/WS → 调 ASGI app
HTTP 一次事务结束标志? 该请求的响应完整结束(流式则写完 body)
HTTP keep-alive 含义? TCP 可复用,多次 HTTP 事务共用连接
WebSocket 任务结束靠? 应用约定 + close,非协议自动判「业务完」
流式 vs WebSocket 本质? 一次响应边写边发 vs 双向消息通道

小结

  • host:port = 寄到哪台机、哪个窗口;TCP = 先接通;HTTP/WebSocket = 接通后用哪种说话规矩。
  • HTTP 结束的是一问一答;TCP 往往还能接着用。
  • WebSocket 是长连接对讲;业务结束点要自己定。
  • 流式仍是 HTTP 的一次响应;WebSocket 是升级后的双向通道——别被「都是多次推数据」骗过去。
  • HTTP 方法(安全/幂等、POST vs PUT vs PATCH)见 02补

下一篇:01 心智模型:ASGI 与请求生命周期

-------------本文结束感谢您的阅读-------------