本系列: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) | 哪台机器 / 哪栋楼 | 127.0.0.1(本机)、0.0.0.0(本机所有网卡对外)、域名 |
| 端口(port) | 这栋楼里的哪个窗口 | 8000、80、443 |
| uvicorn | 守在某个窗口的门房 | uvicorn main:app --port 8000 |
一台机器上同时跑很多程序,不能都抢同一个入口,所以:
- IP / 主机名 → 找到机器
- 端口号(0~65535) → 找到这台机器上的某一个程序
uvicorn 的职责可以记成:
- 在指定
host:port值班(听连接) - 把进来的字节按 HTTP / WebSocket 规则拆开
- 按 ASGI 约定调用你的
app(scope/receive/send)——详见 01
段末注释:TCP(Transmission Control Protocol,传输控制协议)在两台机器间建立可靠字节通道;HTTP(HyperText Transfer Protocol,超文本传输协议)是通道上「请求/响应」的说话方式;WebSocket 是可在同一连接上持续双向传消息的协议。后文沿用缩写。
2. TCP:先接通电话,再说话
访问 http://127.0.0.1:8000/ping 时,底层大致是:
- 用
127.0.0.1找到机器(本机即自己) - 向 8000 端口发起 TCP 连接(握手 ≈「电话接通」)
- 接通后传送的是字节流,本身不懂「这是网页还是聊天」
- 上层协议(HTTP / WebSocket)规定这些字节怎么解读
没有 TCP,就没有稳定通道;没有 HTTP/WebSocket,通道里只是无结构的字节。
1 | 浏览器 / 客户端 |
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 里常表现为一次httpscope 调用)。 - 「会话」若指登录态,那是 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 | 客户端 ──一次 Request──► 服务器 |
- 流里的「多次」≠ 多次独立 HTTP 响应,而是同一个响应体的持续写出。
- 代码形态见 05 流式响应。
WebSocket:
1 | 握手之后: |
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. 合书自测
- 用寄信类比说出 host、port、TCP、HTTP 各像什么。
- 「HTTP 回完响应」是否等于「TCP 一定断开」?为什么?
- WebSocket 上「业务做完」和「连接关闭」分别由谁决定?
- 一句话区分 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 与请求生命周期。