
一、TCP
1、概述
🍉关键词:【面向连接的】【可靠的】【传输层协议】
1 2 3
| TCP是一个面向连接的,可靠的传输层协议。它通过三次握手建立连接,四次挥手断开连接。 具有流量控制和拥塞控制,能保证数据按序、完整、无重复的传输。 应用层的HTTP、HTTPS都是基于TCP的。
|
2、TCP报文段
1 2 3
| TCP报文段是TCP协议在传输数据时的数据单元,由两部分组成: 【TCP头部】携带控制信息,包括源端口、目的端口、序列号、确认号以及SYN、ACK、FIN 等标志位。 【TCP数据部分】携带应用要传输的实际数据,
|
源端口、目的端口:应用程序的唯一标识
序列号:用于标记数据的顺序,标识当前发送的数据段中第一个字节的编号
确认号:用于确认已成功接收的数据,标识接收端期望收到的下一个字节的编号
SYN标志位:标识连接请求,表示这是一个连接请求或响应报文
ACK标志位:用于确认收到报文段
FIN标志位:表示已经完成数据发送,希望关闭连接
Window Size(窗口大小):(接收方)当前最多还能接收多少个字节的数据
3、面向连接
面向连接是网络通信中的一种模式,指的就是在数据传输之前,通信双方需要先建立明确的连接,并且在传输的过程中,维护连接状态,传输完成后释放连接。最典型的例子就是TCP。
🍖三次握手
1 2 3
| 1️⃣ 客户端 → 发送 SYN=1,随机生成序列号 seq = x 2️⃣ 服务器 → 发送 SYN=1 + ACK=1,随机生成初始序列号 seq = y,发送确认号ack=x+1 3️⃣ 客户端 → 发送 ACK=1,发送确认号 ack=y+1,序列号变为 seq=x+1,连接建立!
|
| 步骤 |
方向 |
标志位 |
seq |
ack |
| 1 |
Client→Server |
SYN=1 |
x |
0 |
| 2 |
Server→Client |
SYN=1, ACK=1 |
y |
x+1 |
| 3 |
Client→Server |
ACK=1 |
x+1 |
y+1 |
为什么需要三次握手
1 2 3 4 5 6
| 》 确认双方的收发能力! 1️⃣ 服务器确认客户端能发,服务器能收 2️⃣ 客户端确认服务端能收,能发 3️⃣ 服务器确认客户端能收 》 交换seq序列号,确保数据按序传输 》 通过客户端的最终确认过滤掉无效请求,防止旧连接造成误判
|
🍖四次挥手
因为 TCP 是全双工通信(双方可以独立发送和接收数据),需要分别关闭两个方向的连接。
1 2 3 4
| 1️⃣ 客户端:发送 FIN 请求关闭,发送序列号 seq=u(即已发送数据的最后一个字节序号 +1) 2️⃣ 服务端:ACK=1 确认,确认收到了断开请求,发送确认号 ack=u+1 3️⃣ 服务端:再发送 FIN(也要关闭),发送序列号 seq=v(服务器最后发送的数据序号 +1) 4️⃣ 客户端:ACK=1 确认,发送确认号 ack=v+1,等待一段时间后彻底关闭
|
| 步骤 |
方向 |
标志位 |
seq |
ack |
| 1 |
Client→Server |
FIN=1 |
u |
- |
| 2 |
Server→Client |
ACK=1 |
- |
u+1 |
| 3 |
Server→Client |
FIN=1 |
v |
- |
| 4 |
Client→Server |
ACK=1 |
- |
v+1 |
为什么不是三次
1
| 因为服务器可能在收到 FIN 后仍有数据要发送,不能立即关闭,所以必须分开 ACK 和 FIN。
|
TIME_WAIT 是什么
1 2 3 4
| 客户端发送最后一个 ACK 后,会进入 TIME_WAIT 并保持该状态2MSL之后才会彻底关闭连接。 MSL:TCP 报文在网络中的最大存活时间 》 确保最后一个 ACK 到达服务器 》 确保旧连接的数据包在网络中失效
|
4、可靠
🍔发送速率受两个窗口控制
实际能发送的数据量 = min(接收窗口, 拥塞窗口)
取接收方能力和网络状况的较小值
rwnd:解决接收方缓冲区不足(流量控制)。
- 例如:接收方处理慢 →
rwnd 变小 → 发送方降速。
cwnd:解决网络拥塞(拥塞控制)。
- 例如:网络丢包 →
cwnd 减半 → 发送方降速。
🍖 流量控制
1
| 用于确保发送方的数据【发送速率】不会超过接受方的处理能力,避免接收方的缓冲区溢出,数据丢失
|
为什么需要流量控制
1
| 接收方缓冲区有限,发的太快缓冲区满了就会丢弃数据
|
实现方式:滑动窗口协议
接收窗口:
1
| Receiving Window, rwnd:接收方缓冲区剩余空间,通过 ACK 通告给发送方
|
- 左边界:已发送且已确认的数据的末尾(不可再发送)。
- 右边界:左边界 + 窗口大小(超出右边界的数据暂不可发送)。
- 窗口内:左边界到右边界之间的字节,是【可发送但未确认】的数据范围。
滑动:
1
| 随着接收方确认(ACK)已收到的数据,窗口会“向前滑动”,允许新的数据继续发送。
|
🍖 拥塞控制
1
| 用于避免网络中转节点(如路由器)过载或丢包,通过动态调节【发送速率】,保持网络畅通
|
为什么需要拥塞控制
1
| 链路带宽、路由器缓存等有限承载数据,需要避免网络过载
|
拥塞窗口:
1
| Congestion Window, cwnd:发送方维护的内部变量,表示在当前网络状态下允许发送的未确认数据量上限
|
调控机制
1 2 3 4
| (1)慢启动——每收到一次 ACK,cwnd 翻倍(指数增长) (2)拥塞避免 (3)快重传与快恢复 (4)超时重传(最严重拥塞)
|
🍖 序号与确认应答
保证数据 有序、无重复
序号:
1 2
| 每个 TCP 报文段都有一个序号(Sequence Number) 表示“这个包的数据在整个字节流中的起始位置”
|
确认应答ACK
1
| “我已经收到到第几号字节,你可以继续发第几个字节开始”
|
🍖 超时重传
保证数据 不会永久丢失
1 2 3
| 如果发送方在合理时间内没有收到 ACK,就会触发超时重传机制 TCP 会动态计算超时时间叫做【RTO】 RTO ≈ RTT(往返时延) + 安全裕度 RTT 表示从发送方发出数据到收到接收方 ACK 的总时间(单位:毫秒)
|
🍖 校验和
保证数据 没有被篡改或损坏
1 2 3 4 5
| TCP 报文段会带一个校验和字段
发送方发送前,对数据做一次校验和计算,填入报文头 接收方收到数据后也计算一次校验和 如果校验和对不上,说明数据在传输过程中发生了损坏,会被直接丢弃,不回复 ACK,发送方超时后重传
|
5、应用场景
1
| HTTP/HTTPS、文件传输FTP、电子邮件SMTP、远程登录SSH、数据库连接MySQL
|
二、UDP
1、概述
🍉关键词:【无连接】【不可靠】【高效】【传输层协议】
1
| UDP 是一种无连接、不可靠但高效的传输层协议,它不进行握手,不保证顺序和可靠性,适合对时效性要求高、可以容忍丢包的应用场景,如视频、语音、DNS 查询等。相比 TCP更轻量,需要应用层自行处理错误与丢包问题
|
2、UDP报文段
| 字段 |
说明 |
| 源端口号 |
发起端口 |
| 目标端口号 |
目标端口 |
| 长度 |
整个 UDP 包长度 |
| 校验和 |
简单错误检测 |
3、应用场景
| 应用场景 |
原因说明 |
| 视频直播、语音通话 |
容忍丢包,低延迟优先 |
| DNS 查询 |
查询包小,丢了就重发 |
| 在线游戏 |
要求快速同步状态,宁可偶尔丢帧 |
| QUIC 协议(HTTP/3) |
基于 UDP 实现自己的可靠机制,绕过 TCP 层限制 |
为什么 UDP 没有粘包问题?
1
| UDP 是面向数据报的协议:每个 send() 对应一个完整的报文,接收方每次 recv() 读取一个完整包
|
三、TCP/UDP常考
TCP 和 UDP 有什么区别?
| 对比点 |
TCP |
UDP |
| 是否连接 |
面向连接(三次握手) |
无连接(不建立连接) |
| 是否可靠 |
可靠传输(确认应答、重传、序号) |
不可靠(无确认、无重传) |
| 有序性 |
有序,按序号排列 |
无序,收到就处理 |
| 传输效率 |
相对较慢(连接、确认) |
高效,适合实时场景 |
| 头部开销 |
大(20字节以上) |
小(8字节) |
| 应用场景 |
网页、文件、邮件、SSH、数据库 |
视频、语音、直播、DNS、游戏 |
TCP 为什么比 UDP 更可靠?
1 2 3 4 5
| 流量控制 + 拥塞控制:保证网络不崩溃,避免丢包 序号机制:保证数据有序 确认应答(ACK)机制:收到就回传确认 超时重传机制:丢包自动重发 校验和:保证数据未被损坏
|
UDP 是否可靠?能否通过上层协议实现可靠性?
1 2
| UDP 本身不可靠:无序、无确认、无重传 但可以通过应用层封装实现可靠性(如 QUIC
|
什么场景适合用 TCP,什么场景用 UDP?为什么?
1 2
| TCP:网页、文件传输、数据库、邮件等 → 可靠为主 UDP:视频通话、在线游戏、实时直播 → 低延迟为主
|
为什么视频通话使用 UDP 而不是 TCP?
1 2
| 视频对延迟要求高,UDP 无连接开销、无需重传,速度快 TCP 会因丢包重传、拥塞控制导致延迟,体验差
|