TCP 与 UDP 的全面解析:从基础概念到实际应用

前言(认识TCP/UDP报文格式)

字段名称 位数 说明
源端口(Source Port) 16 位 发送方端口号
目的端口(Destination Port) 16 位 接收方端口号
UDP 长度(Length) 16 位 UDP 头 + 数据总长度
校验和(Checksum) 16 位 检测错误
数据(Data) 可变 实际传输内容
字段名称 位数 说明
源端口(Source Port) 16 位 发送方端口号
目的端口(Destination Port) 16 位 接收方端口号
序列号(Sequence Number) 32 位 用于分片排序、可靠传输
确认号(Acknowledgment Number) 32 位 用于确认收到的数据
首部长度(Header Length) 4 位 TCP 头部长度
保留字段(Reserved) 6 位 保留未用
标志位(Flags) 6 位 URG、ACK、PSH、RST、SYN、FIN
窗口大小(Window Size) 16 位 流量控制
校验和(Checksum) 16 位 错误检测
紧急指针(Urgent Pointer) 16 位 URG 数据偏移
选项(Options) 可变 可选字段,如 MSS、窗口扩大等
数据(Data) 可变 实际传输内容

1.TCP/IP基础概念

1.1TCP是什么?

TCP(Transmission Control Protocol,传输控制协议)是一种 面向连接、可靠、有序 的传输协议。

✅ 核心特点:

面向连接:通信前必须先"握手"建立连接(三次握手),结束后要"挥手"断开(四次挥手)。

可靠传输:确保数据不丢失、不重复、按顺序到达。如果丢包,会自动重传。

流量控制 & 拥塞控制:防止发送太快导致接收方或网络崩溃。

字节流服务:应用层发的数据被看作连续的字节流,没有消息边界。

📌 举个例子:

当你用浏览器打开一个网页(比如百度),背后就是通过 TCP 下载网页内容------必须保证每一张图片、每一行文字都完整无误地传到你电脑上。

💡 常见用途:

网页浏览(HTTP/HTTPS)

电子邮件(SMTP、IMAP)

文件传输(FTP)

数据库连接

✅ 适合对"准确性"要求高的场景。

1.2TCP的报文格式及说明

1.3UDP 是什么?

UDP(User Datagram Protocol,用户数据报协议)是一种 无连接、不可靠、高效 的传输协议。

✅ 核心特点:

无连接:不需要建立连接,直接发送数据。

不可靠:不保证数据一定到达,也不重传、不排序。

低延迟、高效率:头部只有 8 字节,处理快,适合实时通信。

保留消息边界:每次发送就是一个独立的数据包("数据报")。

📌 举个例子:

你在玩《王者荣耀》时,你的操作(比如移动、释放技能)通过 UDP 发送给服务器。即使偶尔丢掉一个操作包,游戏也能继续,但若用 TCP 等待重传,就会明显卡顿。

💡 常见用途:

视频会议(Zoom、腾讯会议)

在线游戏

直播(如抖音直播、B站直播)

DNS 域名查询

物联网(IoT)设备通信

✅ 适合对"速度"和"实时性"要求高、能容忍少量丢包的场景。

1.4UDP的报文格式及说明

2.TCP和UDP的核心区别

对比项 TCP UDP
连接方式 面向连接(建立连接后传输) 无连接(直接发包)
可靠性 可靠传输:确认应答、重传机制 不可靠传输:不保证送达
顺序性 保证数据包按顺序到达 不保证顺序
传输速度 相对较慢(处理机制多) 非常快(协议更轻量)
传输模式 字节流(Stream) 数据报(Datagram)
头部开销 较大(至少 20 字节) 很小(8 字节)
流量控制 支持(滑动窗口) 不支持
拥塞控制 支持(慢启动、拥塞避免等) 不支持
错误检测 有校验+重传 仅校验,无重传
适用场景 文件传输、HTTP、邮件、SSH 等可靠性高的应用 视频直播、语音通话、DNS、实时游戏等实时性要求高的应用
是否有握手/挥手 有:三次握手、四次挥手 无:直接发送
数据边界 无边界(连续字节流) 有边界(按数据包发送)

3. TCP 的关键机制(重点)

3.1三次握手(Three-Way Handshake)

🔁 握手过程

TCP 是面向连接的协议,通信前必须建立连接。三次握手确保双方都能正常收发数据。

步骤 发送方 → 接收方 标志位 说明
1 客户端 → 服务端 SYN=1, seq=x 客户端发起连接请求,随机初始序号 x
2 服务端 → 客户端 SYN=1, ACK=1, seq=y, ack=x+1 服务端确认客户端请求,并发送自己的初始序号 y
3 客户端 → 服务端 ACK=1, seq=x+1, ack=y+1 客户端确认服务端的 SYN,连接建立完成

✅ 此后双方进入 ESTABLISHED 状态,可正常传输数据。

❓ 为什么需要"三次"?两次行不行?
核心原因:防止历史重复连接请求造成资源浪费或错误连接。
假设只有两次握手:

  • 客户端发送 SYN,但因网络延迟很久才到达服务端;
  • 此时客户端早已超时重发或放弃;
  • 服务端收到"过期"的 SYN,误以为是新连接,直接分配资源并回复 ACK;
  • 但客户端不会响应(因为它没发起新连接),导致服务端白白占用资源

三次握手解决了这个问题:

  • 第三次 ACK 由客户端发出,表明它确实想建立连接;
  • 如果是旧 SYN,客户端不会发第三次 ACK,服务端就不会真正建立连接。

✅ 三次握手能双向确认双方的发送和接收能力都正常,且避免历史连接干扰。

3.2四次挥手(Four-Way Wavehand / Connection Termination)

TCP 连接是全双工的(双方可同时收发),所以关闭需要各自独立关闭方向。

🔁 挥手过程

步骤 发送方 → 接收方 标志位 说明
1 主动关闭方 → 被动方 FIN=1, seq=u 主动方(如客户端)数据发送完,请求关闭
2 被动方 → 主动方 ACK=1, seq=v, ack=u+1 被动方确认 FIN,但可能还有数据要发
3 被动方 → 主动方 FIN=1, seq=w, ack=u+1 被动方数据也发完,请求关闭
4 主动方 → 被动方 ACK=1, seq=u+1, ack=w+1 主动方确认,连接完全关闭

📌 注意:步骤 2 和 3 不能合并(除非被动方恰好没有数据要发),所以通常是四次。

⏳ 为什么有 TIME_WAIT 状态?

主动关闭方在发送最后一个 ACK 后,会进入 TIME_WAIT 状态,持续 2×MSL(Maximum Segment Lifetime,通常 30~120 秒)。

目的有两个:

  • 确保最后一个 ACK 能到达对方
  • 如果 ACK 丢失,被动方会重发 FIN;
  • TIME_WAIT 期间可再次响应 ACK,避免对方无法关闭。
  • 防止旧连接的数据包干扰新连接
  • 网络中可能还有旧连接的"残余数据包";
  • 等待 2×MSL(足够让所有旧包过期),再允许相同四元组(IP+端口)建立新连接。

⚠️ 大量短连接可能导致服务器 TIME_WAIT 过多,占用端口资源(可通过 SO_REUSEADDR 优化)。

3.3滑动窗口(Sliding Window)------ 实现流量控制

🎯 目标:防止发送方发得太快,导致接收方缓冲区溢出。
🔧 工作原理:

  • 接收方在每个 ACK 报文中携带 窗口大小(Window Size) 字段,告诉发送方"我还能接收多少字节"。
  • 发送方根据这个窗口动态调整可发送的数据量。
  • 窗口"滑动":随着数据被确认,窗口向前移动,释放新空间。

示例:

  • 接收方缓冲区 4KB,已用 1KB → 告诉发送方窗口 = 3KB;
  • 发送方最多发 3KB 数据,直到收到新的 ACK 更新窗口。

✅ 滑动窗口实现了端到端的流量控制(Flow Control),保护接收方不被压垮。

3.4拥塞控制(Congestion Control)

目标:防止网络过载(不只是接收方,而是整个路径上的路由器/链路)。

TCP 使用 四个核心算法

1. 慢启动(Slow Start)

  • 初始拥塞窗口(cwnd)很小(如 1 MSS);
  • 每收到一个 ACK,cwnd += 1 MSS → 指数增长(1→2→4→8...);
  • 直到达到 慢启动阈值(ssthresh),转为拥塞避免。

💡 快速探测网络容量,但避免一开始就发太多。
2. 拥塞避免(Congestion Avoidance)

  • cwnd 线性增长:每 RTT 增加 1 MSS(即每个 ACK 增加 1/cwnd);
  • 更温和地探测网络上限。
    3. 快速重传(Fast Retransmit)
  • 当发送方收到 3 个重复 ACK(表示某个包丢失,后续包已到);
  • 不等超时,立即重传丢失的包;
  • 避免长时间等待 RTO(Retransmission Timeout)。
    4.快速恢复(Fast Recovery)
  • 在快速重传后进入;
  • 将 ssthresh 设为当前 cwnd 的一半;
  • cwnd = ssthresh + 3(补偿已收到的重复 ACK 数量);
  • 继续按拥塞避免方式增长,不回到慢启动。

🔄 整体策略:

慢启动 → 拥塞避免 →(丢包)→ 快速重传 + 快速恢复 → 拥塞避免

3.5超时重传(Retransmission Timeout, RTO)

🕒 触发条件:

  • 发送数据后,在 RTO 时间内未收到 ACK;
  • 则认为包丢失,重传该数据段。

⏱️ RTO 如何计算?

  • 基于 RTT(Round-Trip Time) 动态估算;

  • 使用 Jacobson 算法(考虑 RTT 变化和抖动);

公式简化版:

cpp 复制代码
RTO = SRTT + 4 × RTTVAR

其中 SRTT 是平滑 RTT,RTTVAR 是 RTT 方差。

⚠️ 超时重传 vs 快速重传:

机制 触发条件 速度 效率
超时重传 RTO 超时 慢(秒级) 低(网络空闲)
快速重传 收到 3 个重复 ACK 快(毫秒级)

✅ 现代 TCP 优先使用快速重传,超时重传是最后兜底。

3.6 TCP 连接建立(三次握手)与关闭(四次挥手)状态变化表和说明表

✅ TCP 连接建立(三次握手)与关闭(四次挥手)状态变化表

阶段 步骤 客户端(主动方)状态 含义 服务端(被动方)状态 含义
连接建立 初始 CLOSED 无连接 CLOSED 无连接
(三次握手) 1. 客户端发 SYN SYN_SENT 已发送 SYN,等待服务端确认 LISTEN 监听连接请求
2. 服务端回 SYN+ACK SYN_SENT 等待服务端 ACK SYN_RECEIVED 已收到 SYN 并回 ACK,等待客户端最终确认
3. 客户端发 ACK ESTABLISHED 连接已建立,可收发数据 ESTABLISHED 连接已建立,可收发数据
数据传输 --- ESTABLISHED 正常通信中 ESTABLISHED 正常通信中
连接关闭 1. 客户端发 FIN FIN_WAIT_1 已发送 FIN,等待 ACK ESTABLISHED → CLOSE_WAIT 收到 FIN,进入半关闭状态(仍可发数据)
(四次挥手) 2. 服务端回 ACK FIN_WAIT_2 已收到 ACK,等待服务端 FIN CLOSE_WAIT 应用层需调用 close() 才能发 FIN
3. 服务端发 FIN FIN_WAIT_2 等待服务端 FIN LAST_ACK 已发送 FIN,等待客户端确认 ACK
4. 客户端发 ACK TIME_WAIT 等待 2×MSL 后彻底关闭 CLOSED 连接完全关闭
超时后 CLOSED 连接彻底释放 --- ---

🔍 关键状态详解

状态 说明
LISTEN 服务端等待客户端连接请求(调用 listen() 后)
SYN_SENT 客户端已发送 SYN,等待服务端响应
SYN_RECEIVED 服务端收到 SYN 并回复 SYN+ACK,等待客户端 ACK(短暂中间态)
ESTABLISHED 连接已建立,双方可正常收发数据
FIN_WAIT_1 主动关闭方已发送 FIN,等待对方 ACK
FIN_WAIT_2 主动关闭方已收到 ACK,等待对方 FIN(此时不能再发送数据,但可接收)
CLOSE_WAIT 被动关闭方收到 FIN,通知应用层关闭连接,等待本地应用调用 close()
LAST_ACK 被动关闭方已发送 FIN,等待最后 ACK,收到后关闭
TIME_WAIT 主动关闭方确保最后一个 ACK 被接收,并防止旧连接影响新连接(等待 2×MSL)
CLOSED 无连接或连接已完全释放

💡 补充说明

  • ** 谁先发 FIN,谁就是主动关闭方(通常是客户端,但服务端也可主动关闭)。**
  • ** TIME_WAIT 只出现在主动关闭方。**
  • 如果服务端主动关闭,则角色互换,状态变化对称。
  • 大量 TIME_WAIT 是正常现象,但过多可能耗尽端口(可通过调整内核参数优化)。

3.7 总结图(逻辑流程)

cpp 复制代码
连接建立: 三次握手
           ↓
数据传输: 滑动窗口(流量控制)
           ↓
           拥塞控制(慢启动 → 拥塞避免)
                     ↘ 丢包? → 快速重传 + 快速恢复
                     ↘ 超时? → 超时重传 + 慢启动重启
           ↓
连接关闭: 四次挥手 + TIME_WAIT

4. UDP 的核心优势

优势 说明
头部结构简单 8 字节 固定头部(TCP 至少 20 字节),开销极小
无连接 无需握手/挥手,直接发送数据,延迟极低
无重传/确认机制 不因丢包而阻塞或重传,避免卡顿
保留消息边界 每次 send() 对应一个独立数据报,应用层易处理
支持广播/多播 可同时向多个主机发送(TCP 仅支持单播)

⚠️ 注意:这些"优势"本质上是牺牲可靠性换来的效率,适用于能容忍少量丢包的场景。

5. 实际应用场景对比

协议类型 常见应用场景 示例/说明
TCP Web 通信 HTTP / HTTPS(网页加载、API 请求)
远程登录 SSH(安全远程管理服务器)
文件传输 FTP(可靠传输文件)
邮件服务 SMTP / IMAP / POP3(邮件发送与收取)
其他需要可靠性保障的通信 数据必须可靠、有序,不丢不重
UDP 域名解析 DNS(快速查询,无需建立连接)
地址分配 DHCP(广播式发现与响应)
实时视频/音频传输 RTSP、实时直播(低延迟比可靠性更重要)
游戏通信 FPS、MOBA(快速同步位置、状态)
其他实时性要求高的应用 即使丢包也要优先保证低延迟

6.如何选择 TCP 或 UDP

需求/场景 推荐协议 原因说明
需要可靠传输 TCP 有重传、确认、丢包恢复
需要实时性 UDP 无握手、无阻塞,延迟极低
需要保证消息顺序 TCP 内部按序号保证严格的包顺序
要极低延迟 UDP 不确认、不重传,发送即走
允许少量丢包 UDP 丢包不阻塞,适用音视频/游戏
不能接受丢包 TCP 保证可靠、有序
相关推荐
dragoooon346 小时前
[Linux网络——Lesson2.socket套接字 && 简易UDP网络程序]
linux·网络·udp
interception6 小时前
爬虫逆向:websocket实战案例,全国建筑市场
爬虫·websocket·网络协议
i_am_a_div_日积月累_6 小时前
websocket设置和断开机制
网络·websocket·网络协议
Jennifer33K8 小时前
WebSocket!!
网络·websocket·网络协议
AuroraDPY11 小时前
计算机网络:HTTP协议
网络协议·计算机网络·http
小马_66611 小时前
[好记性不如烂笔头]RT_Thread http ota升级踩坑笔记(CRC校验不通过)
笔记·物联网·网络协议·http
心一信息11 小时前
http与https的详细介绍
网络协议·http·https
拾忆,想起11 小时前
Dubbo服务上线无法调用?一站式排查指南来了
服务器·网络·网络协议·tcp/ip·dubbo
工程师华哥13 小时前
网络参考模型:从OSI到TCP/IP的数据传输原理,有图解(附知识点文档)
网络协议·tcp/ip·计算机网络·网络工程师·华为认证·路由技术·网络参考模型