phase 5 part 5: cs algorithms, network-os, web-security topics with tested examples; all 43 stacks pass --strict

This commit is contained in:
Shikui Wang committed 2026-10-23 16:47:11 +08:00
1 parent f695bbd7cc
commit 691f738f5f
22 files changed
+1955 -37

No files matched your search

+101
View File
@@ -0,0 +1,101 @@
---
id: cs.network-os.http-tcp
title: 网络基础:从输入 URL 到页面展示、TCP 握手挥手与粘包、HTTP/1.1 / 2 / 3、HTTPS、长连接与 SSE
type: lesson
domain: cs
stack: [network-os]
tags: [TCP, 三次握手, 四次挥手, TIME_WAIT, 粘包, HTTP/2, HTTP/3, HTTPS, TLS, DNS, keep-alive, SSE, WebSocket]
level: basic
prerequisites: []
est_hours: 3
related: [cs.network-os.os-basics, cs.network-os.scenario.connection-troubleshooting, devops.nginx.https-stream-limit]
week: [14, 16]
order: 1
---
# 网络基础:从输入 URL 到页面展示、TCP 握手挥手与粘包、HTTP/1.1 / 2 / 3、HTTPS、长连接与 SSE
> BOSS直聘 2026-10-23 的调研中有岗位提到计算机基础(网络 / 操作系统)。前端出身的你对 HTTP 和浏览器很熟,这里补齐 TCP 和服务端视角。
## 解释说明
### 从输入 URL 到页面展示(经典题,按层回答)
1. **DNS 解析**:浏览器缓存 → 系统缓存 / hosts → 递归解析器 → 根 / 顶级域 / 权威服务器,得到 IP。
2. **建立连接**:TCP 三次握手;HTTPS 再进行 TLS 握手(TLS 1.3 为 1 个往返);HTTP/3 基于 QUIC(UDP),连接和加密握手合并。
3. **发送请求**,经过 CDN / 负载均衡 / 网关到达应用服务器。
4. **服务器处理并响应**。
5. **浏览器渲染**:解析 HTML 构建 DOM、CSS 构建 CSSOM、合成渲染树、布局、绘制、合成;遇到同步脚本会阻塞解析。
### TCP
- **三次握手**:SYN → SYN+ACK → ACK。为什么是三次:双方都要确认“对方能收到我发的”,并同步初始序号;两次无法防止过期的连接请求被误建立。
- **四次挥手**:FIN → ACK → FIN → ACK(因为一方关闭发送后,另一方可能还有数据要发)。
- **TIME_WAIT**:主动关闭方等待 2MSL,确保最后的 ACK 能被重传、旧连接的报文消失。短连接高并发时,主动关闭方(常常是作为客户端的服务)会积累大量 TIME_WAIT —— 解决办法是**连接复用**(连接池、keep-alive),而不是盲目修改内核参数。
- **可靠传输**:序号与确认、超时重传、滑动窗口(流量控制)、拥塞控制(慢启动、拥塞避免)。
- **字节流,没有消息边界**:“粘包 / 拆包”是应用层没有定义边界导致的,要用分隔符或长度前缀解决(示例中实际演示)。
### HTTP 演进
| 版本 | 关键点 |
| --- | --- |
| HTTP/1.1 | 持久连接(keep-alive);一个连接同一时间只能处理一个请求(队头阻塞),浏览器对同域开多个连接 |
| HTTP/2 | 二进制分帧、多路复用(一个连接并发多个流)、头部压缩;TCP 层的丢包仍会阻塞所有流 |
| HTTP/3 | 基于 QUIC(UDP),解决 TCP 层队头阻塞,连接迁移(切换网络不断开) |
### HTTPS
TLS 用非对称加密(或密钥交换)协商出会话密钥,再用对称加密传输数据;证书由 CA 签名,客户端校验证书链和域名,防止中间人。
### 长连接推送:轮询、SSE、WebSocket
| 方式 | 方向 | 适合 |
| --- | --- | --- |
| 轮询 | 客户端拉 | 简单、低频 |
| **SSE** | 服务器 → 客户端,基于普通 HTTP,文本事件,浏览器自动重连 | **大模型流式输出**(OpenAI 等接口都用它) |
| WebSocket | 双向,独立协议 | 聊天、协同编辑、实时语音 |
## 案例
AI 对话接口用 SSE 流式返回:经过 Nginx 时要关闭缓冲;HTTP/1.1 下浏览器对同一域名的并发连接数有限(通常 6 个),用户开多个标签页时 SSE 连接可能占满,HTTP/2 下多路复用没有这个问题。
## 代码示例
[examples/tcp-basics](examples/tcp-basics/)(只用标准库):
```text
$ python framing.py
发送方 send 了 3 次(每次 4 字节),接收方一次 recv 收到 12 字节 → 三条消息粘在一起,边界丢失
长度前缀分帧:每次只读 3 字节,仍然还原出 3 条完整消息:['第0条', '第1条', '第2条']
```
增量解码器(`test_framing.py` 用 100 种随机切分验证):
```python
def feed(self, data: bytes) -> list[dict]:
self.buf += data
out = []
while len(self.buf) >= HEADER.size:
(n,) = HEADER.unpack_from(self.buf)
if n > self.max_frame:
raise ValueError("帧长度超过上限")
if len(self.buf) < HEADER.size + n:
break
out.append(json.loads(bytes(self.buf[HEADER.size:HEADER.size + n])))
del self.buf[:HEADER.size + n]
return out
```
## 易错点
- 认为一次 `send` 对应一次 `recv`。
- 为了解决 TIME_WAIT 乱改内核参数,而不是复用连接。
- 把 HTTP/2 的多路复用和 HTTP/1.1 的管线化混为一谈。
- 不设置超时(连接超时、读超时),上游挂起时线程 / 协程被耗尽。
## 面试常问
- 从输入 URL 到页面展示发生了什么?
- 为什么 TCP 握手是三次、挥手是四次?TIME_WAIT 的作用?
- HTTP/1.1、2、3 的区别?
- SSE 和 WebSocket 的区别?大模型流式输出为什么常用 SSE?