04 · 计算机网络:HTTP/HTTPS 与 Socket 编程
定位:客户端岗的 HTTP 题集中在版本演进和 HTTPS 原理(登录/热更/资源下载都走它);Socket 题考察你能不能真写过网络代码。本章两块各占一半,学完配着 03 章的 UDP,你就能讲完“从输入 URL 到游戏显示登录界面,再切到战斗同步”的完整链路——面试经典压轴大题。 学完标准:TLS 握手能画出流程并说清“为什么对称+非对称混用”;HTTP/1.1→2→3 各自解决了什么;能白板 TCP 客户端/服务端的 socket 调用序列。
1. HTTP 基础与版本演进
Section titled “1. HTTP 基础与版本演进”HTTP 本体:应用层、请求-响应模式、默认端口 80(HTTPS 443)、无状态(cookie/session/token 补状态)、文本协议(HTTP/3 前都是)。
一次请求的构成:请求行(方法 URL 版本)+ 头(Host/User-Agent/Content-Type…)+ 空行 + 体。常见方法:GET(幂等取)/ POST(交数据)/ PUT(幂等替换)/ DELETE(幂等删)/ HEAD(只要头)——幂等性是追问点:GET/PUT/DELETE 重放无害,POST 不行(所以支付回调要带去重号)。
| 版本 | 传输层 | 解决了什么 | 还剩什么 |
|---|---|---|---|
| 1.0 | TCP,每次请求新建连接 | — | 挥手/握手开销大 |
| 1.1 | TCP + keep-alive 长连接 | 连接复用;管道化(基本没人开);分块传输、缓存控制 | 同一连接请求串行(HOL);文本头冗长 |
| 2 | TCP + 二进制分帧 + 多路复用 | 一条连接并发多流(帧交织),头压缩 HPACK,服务器推送 | TCP 层队头阻塞没解(丢包堵所有流) |
| 3 | QUIC over UDP | 流间独立(丢包只堵一条流)、0-RTT 建连、连接迁移(换网络不断线) | 生态普及中 |
面试金句:“1.1 管的是’别频繁握手’,2 管的是’一条连接上别排队’,3 管的是’UDP 上把 TCP 的队头阻塞也解了’——每一代都在解上一代的主瓶颈。”
状态码(常考分类):2xx 成功(200/204 无内容/206 断点续传);3xx 重定向(301 永久/302 临时/304 缓存有效——配合 ETag/Last-Modified,资源热更就靠它);4xx 客户端错(400/401 未认证/403 拒绝/404/429 限流);5xx 服务端错(500/502 网关/503 过载)。
缓存体系(游戏热更相关):强缓存(Cache-Control: max-age,期内不发请求)→ 协商缓存(ETag/If-None-Match,304 只回“没变”)——资源服务器带宽省一大半的功臣。
2. HTTPS / TLS:为什么要对称 + 非对称混用
Section titled “2. HTTPS / TLS:为什么要对称 + 非对称混用”HTTP 三宗罪:明文(被窃听)、可篡改(运营商插广告)、可冒充(假登录页)。HTTPS = HTTP + TLS,对症下药:加密防窃听、摘要防篡改、证书防冒充。
混合加密的原因(必考):非对称(RSA/ECC)安全但慢(比对称慢百倍级),对称(AES)快但密钥分发是死结(怎么把钥匙安全地给对方?)。所以:握手时用非对称商量出对称密钥,之后全程用对称——安全地分发 + 高效地通信。
TLS 1.2 握手流程(简化记忆版):
- 证书链与防冒充:证书 = 服务器公钥 + 身份信息,由 CA 用 CA 私钥签名;浏览器内置 CA 公钥,逐级验签到根证书。中间人没有 CA 私钥,伪造不出合法证书——信任的根是 CA 体系。
- 防篡改:每条记录带 MAC/AEAD 计数摘要,动一个比特校验就失败。
- TLS 1.3:握手砍到 1-RTT(密钥交换改 ECDHE,前向安全——私钥泄露也解不了历史流量),支持 0-RTT 恢复(重连场景)。
- 追问“既然非对称能加密,为什么不全用?”——性能差百倍;“对称密钥怎么不被中间人拿到?”——它只用服务器公钥加密过、只有私钥能解,中间人截了也解不开。
3. 从 URL 到页面
Section titled “3. 从 URL 到页面”DNS 解析顺序(每一级都有缓存):浏览器缓存 → 系统缓存/hosts → 本地 DNS(运营商/公共 114/8.8.8.8,递归查询)→ 根 → 顶级域(.com)→ 权威 DNS → 拿到 IP(TTL 内缓存住)。协议通常 UDP 53(区域传送才用 TCP)。
全链路串讲(按这条线答,每步都能被追问):
CDN 的位置(追问高频):域名先被 CNAME 到 CDN,按“就近节点”返回边缘 IP——静态资源(热更包)走 CDN 省骨干带宽+降延迟;302 一步和 DNS 一步是两种调度方式。
4. Socket 调用序列
Section titled “4. Socket 调用序列”// TCP 服务端 // TCP 客户端socket(AF_INET, SOCK_STREAM) socket(AF_INET, SOCK_STREAM)bind(addr, port) connect(server_addr) // 发起三次握手listen(backlog) write/send(请求)accept() → 返回连接 fd read/recv(响应)read/recv ↔ write/send close() // 四次挥手close()
// UDP(无连接,一个 socket 收发所有人) // UDP 客户端socket(AF_INET, SOCK_DGRAM) socket(AF_INET, SOCK_DGRAM)bind(addr, port) sendto(数据, 对方addr) // 每发都带地址recvfrom(数据, &对方addr) recvfrom(...)sendto(数据, 对方addr)高频细节(每条都可能被追):
- accept 发生在三次握手的哪一步之后?——握手由内核完成(listen 后 SYN 进队列),accept 只是从“已完成连接队列”取一个连接,它不参与握手。
- 服务端bind前的 SO_REUSEADDR:重启立刻绑定处于 TIME_WAIT 的端口——服务器必写。
- listen 的 backlog:全连接队列长度,打满后新握手被拒(高并发要调)。
- UDP 的 connect:不是建连接,只是绑定默认对端(之后可用 send/recv),省去每次传地址,还能收到该对端的 ICMP 错误。
- 大端序:网络字节序是大端——
htons/htonl/ntohs/ntohl必须过一遍(呼应 02 章大小端题:0x1234网线上是12 34)。 - 阻塞 socket 读写返回值:recv=0 对端关闭;<0 看 errno(EWOULDBLOCK/EINTR);write 可能部分写——循环写到完。
5. 高频面试题 Q&A(合上书能讲)
Section titled “5. 高频面试题 Q&A(合上书能讲)”Q1:HTTP 1.1、2、3 的主要区别? 1.1:长连接复用,但一条连接上请求仍串行(HOL)。2:二进制分帧+多路复用(并发流交织)、HPACK 头压缩,解了应用层 HOL;但 TCP 丢包仍堵所有流。3:QUIC 基于 UDP,流独立交付彻底解 TCP HOL,0-RTT 建连、连接迁移(切 WiFi 不断线)。
Q2:HTTPS 为什么快不了又安全?握手过程? 安全靠三件套:对称加密防窃听、摘要防篡改、CA 证书链防冒充。流程:交换随机数→服务端给证书→客户端验签→用公钥加密预主密钥发回→双方由两个随机数+预主密钥算会话密钥→此后对称加密。混合原因:非对称安全但慢百倍,只用来“传钥匙”;对称快,用来“干活”。
Q3:证书是怎么防中间人的? 证书=公钥+身份+CA 签名。浏览器内置根 CA 公钥逐级验签;中间人替换证书没有对应 CA 私钥签不了名,替换自己的假证书则链验证失败告警。信任根是 CA 体系(所以 CA 被黑是大事故)。
Q4:GET 和 POST 的区别? 语义:GET 取资源(幂等、可缓存、参数在 URL);POST 提交(非幂等、不缓存、参数在体)。安全角度 URL 会被历史/日志记录,敏感数据别放 GET。本质都是 HTTP 报文,技术上传体都能传(浏览器约定不同)。
Q5:301/302/304 分别什么场景? 301 永久重定向(换域名,浏览器记死);302 临时(活动页跳转);304 协商缓存命中(带 If-None-Match/ETag 问服务器“变没变”,没变只回 304 不回体)——资源热更省带宽的核心。
Q6:从输入 URL 到页面显示经历了什么? 按链:DNS 解析(多级缓存递归)→ TCP 三次握手 → TLS 握手 → 发 HTTP 请求(可能命中 CDN/负载均衡)→ 服务端处理返回 → 浏览器解析并拉取子资源(强缓存/304)→ 渲染。登录游戏则再走自定义协议连接游戏服。(能扩展每一步的追问点,此题答得越细越加分。)
Q7:accept 和三次握手的关系? 握手由内核在 listen 后自动完成(半连接队列→全连接队列);accept 只是从全连接队列取出已完成的连接返回 fd,不参与握手。backlog 就是这个队列的长度。
Q8:SO_REUSEADDR 为什么服务器必设? 重启服务时旧连接的 TIME_WAIT 还占着端口,不设的话 bind 报 EADDRINUSE;设了就允许复用,秒级重启不炸。
Q9:UDP 编程和 TCP 编程调用上的区别? UDP:socket(SOCK_DGRAM) 后直接 bind(服务端)就能 sendto/recvfrom,每报文带地址、保边界、无连接管理;TCP:SOCK_STREAM 要 listen/accept/connect,流式无边界(要自己切包=粘包处理)。
Q10:网络字节序是什么?为什么要转换? 网络规定大端序;x86/ARM 日常是小端。多字节字段(端口号、长度前缀)过网前必须 htons/htonl,收到再 ntoh——否则 5000(0x1388)会被看成 34835(0x8813)。判断本机大小端的手写法(union/int 指针)在 02 章自测做过。
Q11:WebSocket 和 HTTP 什么关系? 借 HTTP 完成升级握手(Upgrade 头,101 状态码),之后变成全双工长连接帧协议——适合服务端主动推(聊天/推送);游戏内实时同步一般还是自定义 UDP/TCP 协议。
6. 本章自测(10 题,限时 20 分钟,先自己答再看答案)
Section titled “6. 本章自测(10 题,限时 20 分钟,先自己答再看答案)”1. HTTP/1.1 的 keep-alive 解决了什么?
我的原答:没解决什么?
2. HTTP/2 的多路复用为什么还有队头阻塞?
3. QUIC 连接迁移为什么能"切 WiFi 不断线"?
4. 为什么加密要对称+非对称混用?
5. TLS 里证书验签验的是什么?
我的原答:信任的根在哪?
6. 304 是怎么配合 ETag 工作的?
7. DNS 的递归查询和迭代查询分别发生在哪段?
8. accept 什么时候返回?
我的原答:backlog 满了会怎样?
9. 为什么网络编程要 htons?
10. WebSocket 和普通 HTTP 长连接(轮询/SSE)的区别?
📖 答案(先自己答完再展开)
- 解决频繁建连挥手;没解决同一连接上请求串行(应用层 HOL),也没解决 TCP 层丢包 HOL。
- 多路复用解了“应用层排队”,但流们仍挤在一条 TCP 上——丢一个包,TCP 有序交付把所有流都堵住。
- QUIC 用连接 ID 标识连接而非四元组,IP 一变(WiFi→蜂窝)连接 ID 不变,会话继续。
- 非对称安全但慢百倍级(只配握手传密钥),对称快(配大数据量);各取所长。
- 验 CA 用私钥对“证书内容摘要”的签名(确认公钥归属);根在系统内置的根 CA 公钥。
- 首次响应带 ETag(内容指纹);再次请求带 If-None-Match;服务器比对新旧 ETag,没变回 304(无体),变了回 200+新内容。
- 客户端→本地 DNS 是递归(“你要给我最终答案”);本地 DNS→根/顶级/权威是迭代(“我问一层指一层”)。
- 内核完成三次握手把连接放进全连接队列后,accept 从中取出;backlog 满,新完成的握手被丢弃/客户端收到拒绝重试。
- 网络字节序是大端、x86 是小端;多字节字段不转会按错误数值解释(端口、长度头)。
- WebSocket 握手后是双向帧协议,服务端可随时主动推且低开销;轮询是客户端定时拉(延迟=轮询间隔+浪费)、SSE 只能服务端单向推文本。
7. 进阶追问(答不上来就回来复习)
Section titled “7. 进阶追问(答不上来就回来复习)”- TLS 1.3 的 0-RTT 有什么风险?(重放攻击——只用于幂等请求)
- 前向安全是什么?(ECDHE 每会话临时密钥,私钥泄露解不了历史流量)
- Cookie/Session/JWT 三者取舍?(有状态集中 vs 无状态签名;游戏登录常用“账号服发 token,网关验签”)
- 与 03 章贯通:登录服(HTTPS)和战斗服(UDP)为什么分开?(可靠 vs 低延迟的不同诉求;鉴权与实时同步的关注点分离。登录走本章,战斗走 03 的可靠 UDP)