🐳第一部分:什么是TCP和UDP?
先给结论:TCP 和 UDP 都是传输层协议,负责把数据从一台电脑 “搬” 到另一台电脑,但它们的 “搬运风格” 完全不同
📦 比喻:TCP 像 "打电话",UDP 像 "写信"
- TCP(Transmission Control Protocol,传输控制协议):
就像打电话—— 必须先 “拨通对方号码”(三次握手建立连接),通话中能"实时确认对方听到"(通过确认应答、重传机制保障可靠),挂电话前还要"说清楚再见"(四次挥手断开连接)。
核心是双向确认、实时反馈,确保对话完整、有序。 - UDP(User Datagram Protocol,用户数据报协议):
就像写信—— 写好内容、填完地址,直接丢进邮筒(无需确认对方是否在线)。信寄出去后,不管对方收没收到、内容是否完整(丢包、乱序不管),自己的 "发送任务 "就结束了。
核心是简单快捷、无需等待,追求 “发出去就行”
📌 一句话总结:
TCP 像"实时电话",追求稳、准、全;UDP 像 "投信",追求快、简、省。
🐳第二部分:TCP的三次握手和四次挥手
2.1 TCP的三次握手🌈
🤝1.第一次握手(客户端→服务器)
- SYN 标志位:此时 SYN 标志位被置为 1,表示客户端希望与服务器建立一个 TCP 连接。
- 序列号(Sequence Number,seq):客户端会随机生成一个初始序列号,比如记为 x 。这个序列号用于标识客户端在这个连接中发送的第一个字节的数据,后续发送的数据会基于这个序列号进行编号。 比如后续发送的数据长度为 100 字节,那下一个数据段的起始序列号就是 x + 100。
在第一次握手时,客户端向服务器发送一个带有 SYN 标志位且包含初始序列号 x 的 TCP 报文段,此时该报文段不包含 ACK 标志位,因为还没有收到服务器的确认信息。
🤝2.第二次握手(服务器→客户端)
- SYN 标志位:同样被置为 1 ,这是因为服务器在收到客户端的连接请求后,也同意建立连接,所以使用 SYN 标志位来同步自己的初始序列号。
- 序列号(seq):服务器也会随机生成一个初始序列号,比如记为 y 。
- ACK 标志位:被置为 1,表示服务器对客户端发送的 SYN 报文进行确认。
- 确认号(Acknowledgment Number,ack):其值为客户端初始序列号 x 加 1,即 ack = x + 1 。这表明服务器已经成功收到了客户端的 SYN 报文,并且期望客户端下一次发送的数据从序列号 x + 1 开始。
所以,第二次握手时服务器发送的报文段同时包含了 SYN 和 ACK 标志位,以及服务器自己的初始序列号 y 和对客户端的确认号 x + 1。
🤝3.第三次握手(客户端→服务器)
- ACK 标志位:被置为 1,表示客户端对服务器发送的 SYN + ACK 报文进行确认。
- 确认号(ack):其值为服务器初始序列号 y 加 1,即 ack = y + 1 。这意味着客户端已经成功收到了服务器的 SYN + ACK 报文,并且期望服务器下一次发送的数据从序列号 y + 1 开始。
- 序列号(seq):其值为客户端在第一次握手时发送的初始序列号 x 加 1,即 seq = x + 1 ,这是因为在第一次握手时客户端发送的 SYN 报文也占用了一个序列号
第三次握手时,客户端发送的报文段主要是一个仅包含 ACK 标志位的确认报文,以及对服务器的确认号 y + 1 和自己的序列号 x + 1。
总结
通过这三次握手,客户端和服务器双方都确认了彼此的收发能力正常, 并且就各自的初始序列号达成了一致,从而建立起一个可靠的 TCP 连接,为后续的数据传输做好了准备。
2.2 TCP的四次挥手🌈
❄️一、【核心逻辑】四次挥手的 “灵魂”
为什么需要四次挥手?因为 TCP 是全双工通信(双方可以同时发数据),所以断开连接时:
- 客户端 → 服务器:"我要关了(FIN)"
- 服务器 → 客户端:"收到,等我发完剩余数据(ACK)"
- 服务器 → 客户端:"我也关了(FIN)"
- 客户端 → 服务器:"收到,确认关闭(ACK)"
❄️二、【逐次拆解】四次挥手的报文细节
🤝1. 第一次挥手(客户端 → 服务器):“我没数据要发了,准备关”
- 行为:客户端主动发起断开,发送
FIN
报文。 - 关键字段:
-
- FIN 标志位:置为
1
→ 告诉服务器 “我没数据要发了,准备关闭连接”。 - 序列号(seq):填
u
→ 表示 “这是我最后发的字节流的序列号”(u
是客户端当前已发数据的最后一个序列号 + 1)。 - 确认号(ack):填
v
→ 表示 “我确认收到你之前发的序列号到v - 1
的数据”(v
是服务器最后一次 ACK 的确认号)。
- FIN 标志位:置为
- 类比:你打电话说 “我这边说完了,准备挂了”,并告诉对方 “我最后说的内容是第
u
字节”。
🤝2. 第二次挥手(服务器 → 客户端):“收到关闭请求,等我处理完剩余数据”
- 行为:服务器收到
FIN
后,先回复ACK
确认 “收到关闭请求”,但不立即关闭(可能还有数据没发完)。 - 关键字段:
-
- ACK 标志位:置为
1
→ 告诉客户端 “我收到你的关闭请求了”。 - 序列号(seq):填
v
→ 表示 “这是我当前要发的字节流的序列号”(v
是服务器已发数据的最后一个序列号 + 1)。 - 确认号(ack):填
u + 1
→ 表示 “我确认收到你seq = u
的FIN
报文,期望你后续(如果有)从u + 1
开始发”(但客户端已经没数据发了)。
- ACK 标志位:置为
- 类比:对方说 “好的,我知道你要挂了,等我把最后几句话说完”,并确认 “你最后说的是第
u
字节,我记住了”。
🤝3. 第三次挥手(服务器 → 客户端):“我也没数据发了,你可以关了”
- 行为:服务器处理完所有剩余数据后,主动发送
FIN
报文,告诉客户端 “我也没数据了,现在可以关连接了”。 - 关键字段:
-
- FIN 标志位:置为
1
→ 告诉客户端 “我也没数据要发了,准备关闭”。 - 序列号(seq):填
w
→ 表示 “这是我最后发的字节流的序列号”(w
是服务器处理完剩余数据后的最后一个序列号 + 1)。 - 确认号(ack):填
u + 1
→ 同第二次挥手,继续确认客户端的FIN
报文。
- FIN 标志位:置为
- 类比:对方说 “我说完了,你可以挂了”,并告诉客户端 “我最后说的内容是第
w
字节”。
🤝4. 第四次挥手(客户端 → 服务器):“收到关闭请求,确认关闭”
- 行为:客户端收到服务器的
FIN
后,回复ACK
确认 “收到关闭请求”,并等待 2MSL 时间(确保服务器收到 ACK,避免服务器重发FIN
)后关闭连接。 - 关键字段:
-
- ACK 标志位:置为
1
→ 告诉服务器 “我收到你的关闭请求了”。 - 序列号(seq):填
u + 1
→ 表示 “这是我回应你的 ACK 报文的序列号”(客户端已无数据发,序列号延续之前的逻辑)。 - 确认号(ack):填
w + 1
→ 表示 “我确认收到你seq = w
的FIN
报文,期望你后续(如果有)从w + 1
开始发”(但服务器也没数据发了)。
- ACK 标志位:置为
- 类比:你说 “好的,我知道你说完了,现在彻底挂了”,并确认 “你最后说的是第
w
字节,我收到了”。
完美撒花~
Linux的常见命令:Linux常见的命令(超实用!!!!)-CSDN博客
Linux中jar包脚本:在Linux环境安装JDK17(保姆级教程)_linux安装jdk17-CSDN博客
在Docker里面装PostgreSQL:在Docker里面装PostgreSQL(保姆级别)_docker安装postgresql,设置时区,日志挂载出来,配置文件挂载出来-CSDN博客
在Docker中下载Redis和配置:在Docker中下载Redis和配置(保姆级别)_docker 下载redis-CSDN博客
在Docker中下载MySql和配置:在Docker中下载MySql和配置(超详细!!!)_mysql docker镜像下载-CSDN博客
在Linux系统中安装Docker:在Linux系统中安装Docker(保姆级别)_linux安装docker csdn-CSDN博客
阿里云服务器的购买以及远程连接:阿里云服务器入门教程:购买,配置,远程连接(保姆级别)-CSDN博客
在Linux环境安装JDK17:在Linux环境安装JDK17(保姆级教程)_linux安装jdk17-CSDN博客
在Linux环境安装Redis:在Linux环境安装Redis(保姆级教程)_linux 安装最新版redis-CSDN博客
java中的stream流:Java中的Stream流(保姆级别!!)_流(streams)java,可以定时嘛-CSDN博客
保姆级别idea关联数据库的方式:保姆级别IDEA关联数据库方式、在IDEA中进行数据库的可视化操作(包含图解过程)-CSDN博客
Linux的访问权限:Linux的访问权限(保姆级别)-CSDN博客
如何优雅删除Docker镜像和容器:如何优雅删除Docker镜像和容器(保姆级别)-CSDN博客
最实用的vim指令:最实用的Vi/Vim指令汇总(上手超快!!!)_实用vim-CSDN博客
Git、Gitee、GitHub、GitLab完整讲解:从基础到进阶:
Git、Gitee、GitHub、GitLab完整讲解:从基础到进阶-CSDN博客