60 秒回答模板

HTTP 跑在 TCP 上时,TCP 只提供连续字节流,不保留应用层报文边界,所以不能靠一次 read、recv 或一个 TCP 包判断读完。HTTP/1.x 先读起始行和 Header,遇到空行后根据规则判断 Body:有 Content-Length 就读指定字节数;Transfer-Encoding: chunked 就按 chunk size 逐块读到 0 长度块;某些响应可通过连接关闭结束;HEAD、1xx、204、304 等场景没有响应体或有特殊规则。HTTP/2 则依靠二进制帧头长度和 END_STREAM 标志。

考点 核心机制与工程取舍
难度 中高频面试题
回答目标 按定义、机制、场景讲清楚

深入解析

01

TCP 无边界

发送方一次 write 可能被拆成多次接收,多个 HTTP 报文也可能在一次 read 中被读到。应用层必须维护缓冲区并按协议解析,不能把网络包当报文。

02

Header 结束

HTTP/1.x 先解析起始行和 Header,Header 与 Body 之间用空行分隔。只有 Header 读完整后,才能根据方法、状态码和头字段决定是否还有 Body 以及读多长。

03

Content-Length

Content-Length 明确声明 Body 字节数,解析器读满这个长度才认为消息体结束。若连接复用,后面的字节可能已经属于下一个响应或请求,不能多读后丢弃。

04

Chunked 与关闭

chunked 传输把 Body 切成多个块,每块先给十六进制长度,最后以 0 长度块结束。没有长度信息的老式响应可能以连接关闭作为结束,但这会影响连接复用。

05

特殊分支

HEAD 请求的响应、1xx、204、304 通常没有消息体;CONNECT、升级协议和 HTTP/2/3 又有不同边界机制。答题时能补这些边界,会比只背 Content-Length 更完整。

易错点

  • 认为一次 recv 返回就代表一个 HTTP 包读完。
  • 只回答 Content-Length,漏掉 chunked、连接关闭和无 Body 场景。
  • 连接复用场景下多读或少读,破坏后续报文解析。
  • 忽略异常 Header 组合可能带来的请求走私和安全问题。

面试官追问

为什么不能按 TCP 包判断 HTTP 读完?

TCP 是字节流协议,网络分片、合并、缓冲都会改变应用读到的边界,应用必须按 HTTP 协议字段解析。

Content-Length 和 chunked 同时出现怎么办?

规范上 Transfer-Encoding 优先且这类组合容易引发请求走私风险,服务端应严格校验并拒绝异常报文。

连接复用下多读了怎么办?

多读到的字节要留在连接缓冲区,作为下一个报文继续解析,不能当作当前消息体的一部分丢掉。

HTTP/2 如何表示边界?

HTTP/2 使用二进制帧,每个帧头带长度,流结束由 END_STREAM 标志表示,不再依赖文本 Header 后的 Content-Length 规则来分帧。