什么是TCP

TCP四次挥手

image-20251215104218290

1. 本质目的

  • 完成双向关闭的确认:TCP 是全双工通信,客户端和服务端的发送能力相互独立,需分别关闭并确认,避免单向关闭导致的数据丢失或资源浪费。三次挥手只能完成单向关闭的确认,客户端无法确认服务端是否真的完成了写通道的关闭 —— 可能客户端已经断开,服务端还在发数据,导致数据丢失或资源浪费。
  • 确保服务端数据完整传输:每次挥手对应 “关闭请求→确认关闭” 的单向流程,四次交互能给服务端留出时间发送剩余数据,保证双方都完成了 “停止发送数据 + 接收完对方剩余数据” 的确认,避免数据丢失。

2. 第四次挥手

  • 客户端发送完第四次ACK后,只是完成了 “确认服务端关闭写通道” 的动作,但它不会立刻释放连接资源,而是会进入 TIME_WAIT 状态,等待一个2MSL(两倍报文最大生存时间) 的超时时间。

  • 这个等待的目的是,防止最后一个 ACK 丢失,导致服务端重发 FIN;如果 ACK 丢了,客户端还能在 TIME_WAIT 期间重发 ACK。

  • 服务端收到第四次 ACK 后,立即释放连接资源;客户端需等 2MSL 超时后,才彻底释放资源。

一句话总结:四次挥手是为了在全双工模式下,安全、完整地关闭双向通信通道,且保证服务端数据完整传输

TCP流量控制

TCP 流量控制的本质基于接收方的接收能力,动态调整发送方的发送速率,避免发送方发得太快,导致接收方缓冲区溢出、数据丢失。

核心逻辑可以精简为 「接收方通过窗口告知,发送方按需限流」,关键依赖 TCP 头部的「接收窗口(rwnd)」字段

  1. 接收方在 ACK 报文中,携带自己当前的剩余缓冲区大小(即 rwnd),告诉发送方 “我最多还能接收这么多数据”。
  2. 发送方的实际发送窗口 = min(cwnd, rwnd)(取拥塞窗口和接收窗口的较小值)—— 既要看网络拥塞情况,也要看接收方的处理能力。
  3. 当接收方缓冲区快满时,rwnd 会减小甚至变为 0,发送方就会暂停发送;等接收方处理完数据、腾出缓冲区后,再通过 ACK 告知新的 rwnd,发送方恢复发送。

TCP拥塞控制

本质动态调整发送方的「拥塞窗口(cwnd)」大小,让发送速率适配网络的承载能力,避免因发送过多数据导致网络拥塞、丢包。

拥塞控制流程:

  1. 慢启动

    连接刚建立时,cwnd 很小(比如初始为 1~2 个报文段)。每收到一个 ACK,cwnd 指数增长(1→2→4→8…),快速试探网络能承载的速率。当 cwnd 增长到「慢启动阈值(ssthresh)」时,切换到拥塞避免阶段。

  2. 拥塞避免

    为了不压垮网络,cwnd 改为线性增长(每一个 ACK周期,cwnd加 1,而不是每收到一个 ACK),平稳逼近网络的真实承载上限。

  3. 丢包检测

    若检测到丢包(超时重传或收到 3 次重复 ACK),说明网络拥塞了。

    超时重传的处理更严格—— 会把 ssthresh = 当前cwnd / 2,然后 cwnd 重置为初始值,重新进入慢启动(而不是快速恢复)

  4. 快速重传

    把慢启动阈值 ssthresh 设为当前 cwnd 的一半,并触发快速重传(立刻重传丢失的报文段);

  5. 快速恢复

    进入快速恢复,cwnd 从 ssthresh +3 开始线性增长,不用再慢启动,提升恢复效率,相当于重新进入了拥塞避免阶段。

常见面试题

1. TCP 采用三次握手而非两次的原因

本质是为了在不可靠的信道上建立可靠的连接。

  1. 确认双方的发送、接收能力都正常,保证双方都能够进行可靠通信,两次握手只能验证 “客户端发→服务端收” 的单向通路,无法确认服务端的消息能被客户端收到。
  2. 避免网络中延迟的历史无效连接浪费资源,网络中可能存在延迟的旧 SYN 请求,两次握手会让服务端直接建立连接;而三次握手时,客户端会识别并拒绝这些无效请求(服务器返回的SYN+ACK),不发最终的 ACK,服务端就不会维护空连接。
    • 两次握手:服务端收到 SYN 就 “单方面认定连接建立”,无法判断 SYN 是新是旧,只能被动维护连接;
    • 三次握手:连接的建立需要 客户端的最终确认(第三次 ACK) —— 只有有效请求才会触发客户端发 ACK,历史无效请求会被客户端直接忽略,服务端也就不会白忙活。
← 返回列表