TCP 核心原理:三次握手、四次挥手、粘包拆包、TCP 与 UDP 区别

引言

HTTP、MySQL、Redis 集群间通信、RPC 框架,底层大量场景都建立在 TCP 之上。学网络如果跳过 TCP,后面的很多问题都只能停留在表面。

这一篇重点解决四类高频问题:

  1. 三次握手为什么不能变成两次
  2. 四次挥手到底在关闭什么
  3. 粘包和拆包是怎么来的
  4. TCP 和 UDP 到底该怎么区分

TCP 三次握手

TCP 是面向连接的协议,正式传输数据前,需要先建立连接。

第一次握手:SYN

客户端向服务端发送 SYN 报文,表示要建立连接,并带上自己的初始序列号。

第二次握手:SYN + ACK

服务端收到后,返回 SYN + ACK,表示:

  • 你的请求我收到了
  • 我也愿意建立连接

第三次握手:ACK

客户端再回一个 ACK,表示自己收到了服务端的响应。

到这里,连接建立成功。

为什么不是两次握手

这个问题的关键不是"能不能少一次",而是"能不能确认双方都具备正常收发能力"。

如果只有两次握手,会出现一个问题:

  • 客户端发出 SYN
  • 服务端回应 SYN + ACK
  • 但客户端是否收到了这个响应,服务端并不知道

也就是说,两次握手只能保证:

  • 客户端能发
  • 服务端能收、能发

但不能保证客户端能收,也不能保证双方对连接状态达成一致。

三次握手多出来的最后一次 ACK,本质上就是客户端告诉服务端:

"你的回复我收到了,连接状态可以正式成立。"

此外,它还能帮助避免历史失效连接请求引发的误连接问题。

客户端网络抖动,多发了几次 SYN,为什么不会建立多个连接

这类问题通常由 TCP 的状态机和重传机制保证。

可以从几个角度理解:

超时重传不会凭空创建新连接

如果服务端发出 SYN + ACK 后没有收到客户端的 ACK,它可能会重传 SYN + ACK,但这仍然属于同一次建连尝试。

序列号帮助识别连接尝试

每次新的连接尝试会带上新的初始序列号。服务端会结合四元组和当前状态识别这是不是同一个连接过程。

最终要以 ACK 完成建连

没有最后那一步确认,服务端不会把连接视为真正建立完成。

所以重复 SYN 不等于重复建立连接。

TCP 四次挥手

TCP 是全双工协议,两个方向都可以独立发送数据。因此关闭连接时,通常需要分两边分别关闭。

第一次挥手:FIN

客户端发送 FIN,表示"我这边没有数据要发了"。

第二次挥手:ACK

服务端回复 ACK,表示"我知道你这边发完了"。

第三次挥手:FIN

服务端等自己也发送完剩余数据后,再发 FIN,表示"我这边也结束了"。

第四次挥手:ACK

客户端回复 ACK,连接关闭流程完成。

所以四次挥手不是为了复杂,而是因为:

"一端不再发送数据"和"另一端也不再发送数据"通常不是同一时刻发生的。

TCP 粘包和拆包的原因

很多人第一次接触 TCP 编程时,都会遇到"明明发了三条消息,为什么对面一次收到了两条半"这类问题。

原因在于:

TCP 是面向字节流的协议,它只保证字节流有序、可靠到达,但不保证应用层消息边界。

于是就会出现两种现象。

粘包

发送方连续发送多个小包,接收方可能一次性读到了合并后的数据。

拆包

发送方发出一个大包,接收方可能分多次才读完整。

所以粘包和拆包本质上都不是 TCP 出错,而是应用层自己必须定义消息边界。

粘包和拆包的解决办法

固定长度消息

每条消息长度固定,不够的部分补齐。

优点是实现简单,缺点是浪费空间,也不够灵活。

使用分隔符

例如每条消息末尾加特定分隔符,接收方读到分隔符就认为一条消息结束。

这种方式实现成本低,但要注意分隔符不能和消息内容冲突。

自定义协议头

最常见的做法是消息由"消息头 + 消息体"组成,消息头里写明消息体长度。接收方先读长度,再按长度读取完整消息。

这是工程上最稳妥、最常见的做法。

TCP 和 UDP 的区别

TCP

TCP 的特点:

  • 面向连接
  • 可靠传输
  • 有序到达
  • 有重传、流量控制、拥塞控制

适合对可靠性要求高的场景,比如:

  • Web 请求
  • 数据库连接
  • 文件传输

UDP

UDP 的特点:

  • 无连接
  • 开销小
  • 传输速度快
  • 不保证可靠到达和顺序

适合对实时性要求高、可容忍少量丢包的场景,比如:

  • 语音通话
  • 视频直播
  • 实时游戏

如何回答面试里的 TCP 和 UDP 区别

不要只背"可靠"和"不可靠",建议从下面四个维度回答:

  1. 是否需要建立连接
  2. 是否保证可靠和有序
  3. 协议开销大小
  4. 适合的业务场景

这样回答会更完整。

总结

TCP 最核心的几件事可以总结为:

  1. 通过三次握手建立可靠连接
  2. 通过序列号和确认机制保证可靠传输
  3. 通过四次挥手关闭双向连接
  4. 只提供字节流,不负责应用层消息边界

如果你能把这些点讲清楚,TCP 这部分基础就已经比较扎实了。


如果这篇文章对你有帮助,欢迎继续阅读本系列后续内容。若文中有不准确或需要补充的地方,也欢迎指出。

相关推荐
你觉得脆皮鸡好吃吗1 天前
Check Anti-CSRF Token (AI)
前端·网络·网络协议·安全·csrf·网络安全学习
wuyoula1 天前
AI导航智能决策系统源码 附教程
c++·tcp/ip·源码
不会写DN1 天前
处理 TCP 流中的消息分片
服务器·网络·tcp/ip
小红的布丁1 天前
IP、子网、私有地址、ARP 与 Ping 通信全过程
网络·网络协议·tcp/ip
以太浮标1 天前
华为eNSP综合实验之- 交换机组播VLAN(Multicast-VLAN)详细解析
运维·网络·网络协议·网络安全·华为·自动化·信息与通信
mounter6251 天前
【深度解析】Device Memory TCP:开启高性能网络传输的“零拷贝”新时代
linux·服务器·网络·网络协议·tcp/ip·kernel·devmem
KevinCyao1 天前
彩信http接口如何接入?采用POST方式提交多媒体附件的彩信示例
网络·网络协议·http
北京耐用通信1 天前
破局工业通讯壁垒!耐达讯自动化EtherCAT转RS232网关,老设备焕新核心桥梁
服务器·网络·人工智能·科技·物联网·网络协议·自动化
守护安静星空1 天前
esp32开发笔记-wifi网络
网络·笔记·vscode·单片机·tcp/ip