TCP与UDP

img

一、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
动态调整发送方和接收方之间的数据传输窗口大小

接收窗口:

1
Receiving Window, rwnd:接收方缓冲区剩余空间,通过 ACK 通告给发送方
  • 左边界:已发送且已确认的数据的末尾(不可再发送)。
  • 右边界:左边界 + 窗口大小(超出右边界的数据暂不可发送)。
  • 窗口内:左边界到右边界之间的字节,是【可发送但未确认】的数据范围。

滑动:

1
随着接收方确认(ACK)已收到的数据,窗口会“向前滑动”,允许新的数据继续发送。

🍖 拥塞控制

1
用于避免网络中转节点(如路由器)过载或丢包,通过动态调节【发送速率】,保持网络畅通

为什么需要拥塞控制

1
链路带宽、路由器缓存等有限承载数据,需要避免网络过载

拥塞窗口:

1
Congestion Window, cwnd:发送方维护的内部变量,表示在当前网络状态下允许发送的未确认数据量上限

调控机制

1
2
3
4
1)慢启动——每收到一次 ACK,cwnd 翻倍(指数增长)
2)拥塞避免--接近网络容量时,cwnd 不再指数增长,而是线性增长
3)快重传与快恢复--收到 3 个重复 ACK,立即重传丢失的数据包
4)超时重传(最严重拥塞)--超时未收到ACK,丢包发生,把 cwnd 减半后再进入拥塞避免

🍖 序号与确认应答

保证数据 有序、无重复

序号:

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--Google 推出的 UDP + TLS + TCP 混合协议)

什么场景适合用 TCP,什么场景用 UDP?为什么?

1
2
TCP:网页、文件传输、数据库、邮件等 → 可靠为主
UDP:视频通话、在线游戏、实时直播 → 低延迟为主

为什么视频通话使用 UDP 而不是 TCP?

1
2
视频对延迟要求高,UDP 无连接开销、无需重传,速度快
TCP 会因丢包重传、拥塞控制导致延迟,体验差