【JavaSE】【网络原理】UDP 和 TCP 的原理详解
在 JavaSE 阶段学习网络编程时,理解 UDP 和 TCP 的核心区别与工作原理是最重要的一环,因为 Java 的Socket、ServerSocket、DatagramSocket等类本质上就是在封装这两种传输层协议。
下面用最清晰的对比 + 图解 + 通俗语言,把它们讲透。
一、TCP 与 UDP 核心对比表(2026年面试必背)
| 特性 | TCP(传输控制协议) | UDP(用户数据报协议) | 典型应用场景 |
|---|---|---|---|
| 连接方式 | 面向连接(三次握手、四次挥手) | 无连接 | TCP:HTTP/HTTPS、FTP、SMTP、MySQL UDP:DNS、视频直播、游戏、语音通话 |
| 传输可靠性 | 可靠(丢包重传、乱序重排、流量控制、拥塞控制) | 不可靠(尽力而为,丢包不重传) | — |
| 数据传输方式 | 字节流(无边界) | 数据报(有边界,一发一收) | — |
| 传输效率 | 较低(头部 20 字节 + 各种确认、重传机制) | 较高(头部仅 8 字节) | UDP 更快,但不可靠 |
| 是否提供流量控制 | 有(滑动窗口) | 无 | — |
| 是否提供拥塞控制 | 有(慢启动、拥塞避免、快速重传、快速恢复) | 无 | TCP 更适合广域网 |
| 头部开销 | 20~60 字节(选项字段可变) | 8 字节 | UDP 头部极简 |
| 是否有序 | 有序(序号 + 确认机制) | 无序(应用层自己处理) | — |
一句话总结:
- TCP= 可靠的、面向连接的、字节流的“快递员”(保证送达、按序送达、不丢失、不重复)
- UDP= 不可靠的、无连接的、数据报的“发射炮”(发出去就不管了,速度快)
二、TCP 核心原理(三次握手、四次挥手、滑动窗口)
1. 三次握手(建立连接)
目的:双方确认对方的发送和接收能力都正常
客户端 服务端 | SYN=1, seq=x | (我能发,你能收吗?) |----------------->| | | SYN=1, ACK=1, seq=y, ack=x+1 | | (我也能发,你也能收) |<-----------------| | ACK=1, seq=x+1, ack=y+1 | (好的,大家都能发能收,开始吧) |----------------->|为什么是三次而不是两次?
两次无法确认客户端的接收能力(第二次握手确认服务端收发正常,但客户端只确认了服务端能收)
2. 四次挥手(断开连接)
目的:双方都确认数据全部发送完毕,且对方不再发送
客户端 服务端 | FIN=1, seq=u | (我发完了,你呢?) |----------------->| | | ACK=1, ack=u+1 | | (收到,我还在发) |<-----------------| | | FIN=1, seq=v | | (我也发完了) |<-----------------| | ACK=1, ack=v+1 | (好的,结束) |----------------->|为什么是四次而不是三次?
因为 TCP 是全双工,双方都要独立关闭自己的发送通道。
3. 滑动窗口与流量控制(TCP 高效传输的关键)
- 窗口大小:接收方告诉发送方“我还能接收多少字节”
- 滑动窗口:发送方根据窗口大小决定一次能发多少数据
- 零窗口:接收方窗口为 0 → 发送方停止发送(避免淹没接收方)
三、UDP 核心原理(简单粗暴)
UDP 数据报格式(只有 8 字节头部)
源端口 (16位) | 目的端口 (16位) 长度 (16位) | 校验和 (16位) 数据...UDP 特点总结
- 无连接 → 无三次握手、无四次挥手,开销极小
- 无状态 → 不记录连接状态,适合一对多广播、组播
- 数据报边界保留 → send 多少,recv 就完整收到多少(不像 TCP 是流)
- 无重传、无拥塞控制 → 应用层自己决定是否重传
四、Java 中对应实现(最常考)
| 协议 | Java 类 | 特点 | 典型代码片段 |
|---|---|---|---|
| TCP | ServerSocket / Socket | 面向连接、可靠、流式 | server.accept()→socket.getInputStream() |
| UDP | DatagramSocket / DatagramPacket | 无连接、不可靠、数据报 | socket.send(packet)/socket.receive(packet) |
UDP 经典代码示例(广播/组播常见)
// 发送端DatagramSocketsocket=newDatagramSocket();Stringmsg="Hello UDP";byte[]data=msg.getBytes();DatagramPacketpacket=newDatagramPacket(data,data.length,InetAddress.getByName("255.255.255.255"),9999);// 广播socket.send(packet);// 接收端DatagramSocketsocket=newDatagramSocket(9999);byte[]buffer=newbyte[1024];DatagramPacketpacket=newDatagramPacket(buffer,buffer.length);socket.receive(packet);Stringreceived=newString(packet.getData(),0,packet.getLength());五、2025-2026 年面试高频问题(建议背熟)
- TCP 和 UDP 的区别?分别适用于什么场景?
- 为什么 UDP 比 TCP 快?(无连接、无状态、无重传、无拥塞控制)
- 三次握手为什么是三次而不是两次?
- 四次挥手为什么是四次?TIME_WAIT 状态有什么作用?(防止延迟数据包干扰新连接)
- TCP 如何保证可靠传输?(确认应答、超时重传、滑动窗口、流量控制、拥塞控制)
- UDP 什么时候会丢包?(网络拥堵、接收方缓冲区满)
- Java 中实现 UDP 广播/组播要注意什么?(设置
setBroadcast(true),组播地址 224.0.0.0~239.255.255.255)
一句话总结:
TCP是“稳重可靠的大哥”,适合需要数据完整、顺序的场景(网页、文件传输、数据库)。
UDP是“速度至上的小弟”,适合实时性要求高、丢包可容忍的场景(直播、游戏、DNS)。
如果你正在准备 JavaSE 网络编程面试,或者想看具体代码案例(TCP 聊天室、UDP 广播、组播实现),可以告诉我,我继续给你展开~