TCP
TCP
在高级前端面试中,TCP 的考察重点不仅是“三次握手四次挥手”的背诵,而是深挖其可靠性保障机制(流量控制与拥塞控制),以及它在现代 Web 性能瓶颈中的表现。
TCP 三次握手和四次挥手
三次握手 (建立连接,同步双方序列号 ISN)
- 客户端发
SYN(进入 SYN_SENT 状态) - 服务端返回
SYN + ACK(进入 SYN_RCVD 状态) - 客户端返回
ACK(双方进入 ESTABLISHED 状态)面试追问:为什么不能是两次握手? 防止已失效的连接请求报文段突然又传送到了服务端,产生错误。如果是两次,服务端只要发出 ACK 就建立连接,但如果客户端其实并没有发起有效连接,服务端的资源就会一直挂着被浪费(这也是 SYN Flood 攻击的原理)。
四次挥手 (全双工通信,需要双方分别关闭)
- 客户端发
FIN,表示没有数据要发送了 (进入 FIN_WAIT_1) - 服务端发
ACK,表示收到了,但可能还有数据没发完 (进入 CLOSE_WAIT) - 服务端发
FIN,表示服务端的数据也发完了 (进入 LAST_ACK) - 客户端发
ACK,表示知道你发完了 (进入 TIME_WAIT,等待 2MSL 后彻底关闭)面试追问:为什么要等待 2MSL (Maximum Segment Lifetime)?
- 保证客户端发送的最后一个 ACK 报文段能够到达服务端(如果丢了,服务端会重发 FIN)。
- 防止“已失效的连接请求报文段”出现在本连接中,让网络中延迟的包死透。
TCP 如何保证可靠传输 (核心机制)
- 确认应答与超时重传:每个包都有序号,接收方收到后回复 ACK。如果发送方在 RTO (Retransmission TimeOut) 内没收到 ACK,就会重传。
- 流量控制 (滑动窗口)
- 作用:保护接收方,防止发送方发得太快导致接收方缓存被打爆。
- 原理:接收方在 ACK 中携带自己的“接收窗口 (rwnd)”大小,发送方根据这个值动态调整自己的发送窗口。
- 拥塞控制
- 作用:保护网络链路,防止整个网络拥堵。
- 四大算法:
- 慢启动:刚开始连接时,拥塞窗口 (cwnd) 呈指数级增长。
- 拥塞避免:到达慢启动门限 (ssthresh) 后,变为线性增长。
- 快速重传:如果连续收到 3 个相同的重复 ACK(说明中间有包丢了),不等超时时间,立刻重传丢失的包。
- 快速恢复:遇到快速重传时,门限减半,cwnd 设置为新的门限值,然后开始拥塞避免(线性增长)。
TCP 对比 UDP
| 维度 | TCP | UDP |
|---|---|---|
| 连接状态 | 面向连接(需握手) | 无连接(直接发包) |
| 可靠性 | 高(确认机制、重传机制) | 低(尽最大努力交付,不保证送达) |
| 传输效率 | 较慢(开销大,头部 20 字节,有队头阻塞) | 极快(开销小,头部 8 字节) |
| 流控与拥塞 | 有流量控制和拥塞控制 | 无,网络拥堵也会继续发 |
| 前端应用场景 | HTTP/1.1, HTTP/2, WebSocket | WebRTC (视频通话), HTTP/3 (QUIC) |
前端实战思考:为什么 HTTP/3 要换成基于 UDP 的 QUIC 协议? TCP 虽然可靠,但它的重传机制会导致队头阻塞(Head-of-line Blocking)。在 HTTP/2 中,多个请求复用一个 TCP 连接,如果底层 TCP 丢了一个包,整个 TCP 连接必须等待重传,导致所有 HTTP 请求全部卡住。QUIC 基于 UDP,在应用层实现了可靠性,并且各个流互相独立,彻底解决了这个致命痛点。