跳到主要内容

TCP 与 UDP

问题

TCP 和 UDP 有什么区别?TCP 三次握手和四次挥手的过程是什么?

答案

TCP vs UDP 对比

维度TCPUDP
连接面向连接(三次握手)无连接
可靠性可靠(重传、确认、排序)不可靠(尽最大努力交付)
传输方式字节流数据报
有序性保证顺序不保证顺序
流量控制滑动窗口
拥塞控制有(慢启动等)
头部开销20 字节8 字节
速度较慢
典型应用HTTP、FTP、SMTPDNS、视频直播、游戏

三次握手

  1. 第一次握手:客户端发送 SYN,进入 SYN_SENT 状态
  2. 第二次握手:服务端收到 SYN,回复 SYN+ACK,进入 SYN_RCVD 状态
  3. 第三次握手:客户端收到 SYN+ACK,回复 ACK,双方进入 ESTABLISHED 状态
为什么是三次而不是两次?

两次握手无法防止历史连接的干扰。假设客户端发了一个旧的 SYN(网络延迟),两次握手时服务端收到后直接建立连接,浪费资源。三次握手中客户端收到 SYN+ACK 后能判断是否是过期连接,不回复 ACK 即可拒绝。

四次挥手

  1. 第一次挥手:客户端发送 FIN,表示不再发送数据
  2. 第二次挥手:服务端回复 ACK,确认收到(此时服务端可能还有数据要发)
  3. 第三次挥手:服务端发送 FIN,表示数据发送完毕
  4. 第四次挥手:客户端回复 ACK,进入 TIME_WAIT 等待 2MSL 后关闭
为什么需要 TIME_WAIT(2MSL)?
  1. 确保最后的 ACK 能到达服务端:如果服务端没收到 ACK 会重发 FIN,TIME_WAIT 期间可以重新回复
  2. 确保旧连接的报文段在网络中消失:防止和新连接混淆

可靠传输机制

机制说明
序号与确认每个字节编号,接收方确认收到的序号
超时重传超过 RTO 未收到 ACK,重新发送
滑动窗口控制发送速率,接收方通告可用窗口大小
拥塞控制慢启动 → 拥塞避免 → 快重传 → 快恢复

常见面试问题

Q1: 为什么挥手要四次而不是三次?

答案

握手时服务端可以把 SYN 和 ACK 合并在一次发送。但挥手时,服务端收到 FIN 后可能还有数据没发完,所以先回 ACK(确认收到关闭请求),等数据发完再发 FIN。ACK 和 FIN 不能合并,所以需要四次。

但如果服务端没有数据要发了,TCP 延迟确认机制可能会把 ACK 和 FIN 合并,实际抓包可能只看到三次挥手。

Q2: 大量 TIME_WAIT 怎么处理?

答案

高并发短连接场景(如 HTTP 1.0)主动关闭方会产生大量 TIME_WAIT,占用端口资源。

解决方案:

  1. tcp_tw_reuse:允许复用 TIME_WAIT 的端口
  2. 使用长连接(HTTP Keep-Alive)减少连接关闭次数
  3. 让服务端主动关闭(让客户端承担 TIME_WAIT)

Q3: 大量 CLOSE_WAIT 说明什么?

答案

CLOSE_WAIT 出现在被动关闭方(收到 FIN 但还没发 FIN)。大量 CLOSE_WAIT 说明应用程序没有正确关闭连接——收到对方关闭请求后,自己忘了调用 close()。通常是代码 Bug(如连接/流没有在 finally 中关闭)。

Q4: TCP 粘包/拆包是什么?

答案

TCP 是字节流协议,不保留消息边界。发送方的多次 write 可能被合并为一次发送(粘包),或一次 write 被拆成多次发送(拆包)。

解决方案:

  1. 固定长度:每个消息固定长度
  2. 分隔符:用特殊字符分隔消息(如 \r\n
  3. 长度前缀:消息头部包含消息体长度(最常用)

Q5: UDP 有什么优势场景?

答案

  • DNS 查询:一问一答,不需要建立连接
  • 视频/音频直播:实时性要求高,丢几帧可以接受
  • 游戏:低延迟优先,自行在应用层处理可靠性
  • QUIC(HTTP/3):基于 UDP 实现可靠传输,兼顾性能和可靠性

相关链接