你有没有想过:同样是上网发消息,为啥微信发文字很少丢消息,而直播时偶尔会卡顿花屏?其实这背后是两种不同的传输协议在工作 ——TCP 和 UDP。很多人搞不懂这俩到底有啥区别,今天用大白话给你讲明白,再用代码演示两者的工作方式,看完你就知道:为啥传文件用 TCP,玩游戏用 UDP 了!
一、先搞懂:TCP 和 UDP 的核心区别 ——“靠谱” 和 “飞快” 的选择
TCP 和 UDP 都是计算机之间传输数据的 “快递员”,但工作风格完全不同,用两个生活中的例子就能分清:
TCP 就像 “挂号信”:
寄信前要先确认对方地址能收到(建立连接),信寄出去后要等对方说 “收到了”(确认机制),如果信丢了会重新寄(重传机制),直到对方收到为止。优点是 “靠谱”,缺点是 “慢”(流程多)。
UDP 就像 “普通平信”:
写好信直接扔邮筒,不管对方能不能收到,也不等回复,丢了也不重寄。优点是 “快”(流程少),缺点是 “不靠谱”(可能丢信)。
举个直观的例子:
你用微信发文字消息:用的是 TCP 思路 —— 必须保证对方收到,哪怕慢点也没关系,不然 “借钱” 的消息没收到就麻烦了;
你看直播时的画面:用的是 UDP 思路 —— 哪怕偶尔丢几帧画面(卡顿一下),也比等缓冲完再播强,毕竟直播要实时。
二、4 个核心区别:一张表看清,再也不混淆
很多人记不住 TCP 和 UDP 的区别,其实对比 “连接方式、可靠性、速度、用途” 这四点,立马就能分清:
对比维度 TCP(传输控制协议) UDP(用户数据报协议)
连接方式 面向连接(发数据前要 “三次握手” 建立连接) 无连接(发数据前不用打招呼,直接发)
可靠性 保证可靠(数据不丢、不重复、按顺序到) 不保证可靠(可能丢数据、乱序)
速度效率 较慢(流程多,要确认、重传) 较快(流程少,不用等确认)
数据大小 能传大量数据(比如几 GB 的文件) 适合小数据(一次最多传 64KB)
典型用途 下载文件、浏览网页、发邮件 直播、视频通话、在线游戏、GPS 定位
补充:TCP 的 “三次握手” 是啥?—— 就像打电话确认
TCP 建立连接的 “三次握手”,其实和打电话的流程很像:
你打给朋友:“喂,你在吗?”(客户端发连接请求);
朋友回复:“我在,你能听到吗?”(服务器确认收到,也发个请求);
你再说:“能听到,我要说话了”(客户端再确认,连接建立)。
三次握手后,双方才开始正经传数据,这就是 TCP “靠谱” 的基础 —— 确保双方都准备好接收了。而 UDP 就像 “对讲机喊一声就挂”,不管对方听没听到。
三、实战案例:用代码演示 TCP 和 UDP 的工作方式
光说理论没用,我们用 “客户端给服务器发消息” 的场景,分别用 TCP 和 UDP 实现,看看两者的代码和效果有啥不同。
1. TCP 通信代码(靠谱但步骤多)
TCP 需要先建立连接,再传数据,就像 “先拨号再说话”:
java
运行
// TCP服务器端
import java.io.*;
import java.net.*;
public class TCPServer {
public static void main(String[] args) throws IOException {
// 1. 创建服务器Socket,绑定8888端口
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("TCP服务器启动,等待客户端连接...");
// 2. 等待客户端连接(阻塞,直到有客户端连过来)
Socket clientSocket = serverSocket.accept();
System.out.println("客户端已连接:" +
clientSocket.getInetAddress());
// 3. 获取输入流,读取客户端发的消息
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream())
);
String message = in.readLine();
System.out.println("收到客户端消息:" + message);
// 4. 给客户端回消息(确认收到)
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true
);
out.println("服务器已收到:" + message);
// 5. 关闭连接(断开电话)
in.close();
out.close();
clientSocket.close();
serverSocket.close();
}
}
java
运行
// TCP客户端
import java.io.*;
import java.net.*;
public class TCPClient {
public static void main(String[] args) throws IOException {
// 1. 连接服务器(拨号)
Socket socket = new Socket("localhost", 8888);
System.out.println("已连接TCP服务器,准备发消息...");
// 2. 发消息给服务器
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true
);
out.println("你好,我是TCP客户端");
// 3. 等服务器回复(确认收到)
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream())
);
String response = in.readLine();
System.out.println("收到服务器回复:" + response);
// 4. 关闭连接
out.close();
in.close();
socket.close();
}
}
TCP 运行效果:
plaintext
// 服务器端
TCP服务器启动,等待客户端连接...
客户端已连接:/127.0.0.1
收到客户端消息:你好,我是TCP客户端
// 客户端
已连接TCP服务器,准备发消息...
收到服务器回复:服务器已收到:你好,我是TCP客户端
特点:步骤多(先连接、再发消息、等回复、最后断开),但消息一定能到,还能收到确认。
2. UDP 通信代码(快但简单粗暴)
UDP 不用建立连接,直接发消息,就像 “往对方邮箱扔信,不管收没收到”:
java
运行
// UDP服务器端
import java.net.*;
public class UDPServer {
public static void main(String[] args) throws Exception {
// 1. 创建UDP套接字,绑定9999端口
DatagramSocket socket = new DatagramSocket(9999);
System.out.println("UDP服务器启动,等待消息...");
// 2. 准备缓冲区,接收消息
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// 3. 接收客户端消息(阻塞,等消息来)
socket.receive(packet);
String message = new String(packet.getData(), 0, packet.getLength());
System.out.println("收到客户端消息:" + message);
// 4. (可选)不给客户端回消息(UDP不保证回复)
// ...
// 5. 关闭套接字
socket.close();
}
}
java
运行
// UDP客户端
import java.net.*;
public class UDPClient {
public static void main(String[] args) throws Exception {
// 1. 创建UDP套接字(不用连接服务器)
DatagramSocket socket = new DatagramSocket();
// 2. 准备要发的消息
String message = "你好,我是UDP客户端";
byte[] data = message.getBytes();
// 3. 直接发消息(指定服务器地址和端口)
DatagramPacket packet = new DatagramPacket(
data, data.length, InetAddress.getByName("localhost"), 9999
);
socket.send(packet);
System.out.println("UDP消息已发送,不管对方收没收到");
// 4. 直接关闭(不等回复)
socket.close();
}
}
UDP 运行效果:
plaintext
// 服务器端
UDP服务器启动,等待消息...
收到客户端消息:你好,我是UDP客户端
// 客户端
UDP消息已发送,不管对方收没收到
特点:步骤少(直接发消息,不用等连接和回复),速度快,但如果服务器没启动,客户端也不知道消息丢了。
四、选 TCP 还是 UDP?看场景!3 个记住不纠结
开发时选哪种协议,不用死记硬背,看你的需求更在意 “靠谱” 还是 “快”:
需要 “数据不能丢”—— 用 TCP:
下载文件(丢了一块就损坏了);
网上购物付款(付款信息丢了就麻烦了);
发邮件(总不能邮件发一半没了)。
需要 “速度快、实时性高”—— 用 UDP:
直播 / 视频通话(丢几帧画面不影响,总比卡顿强);
在线游戏(玩家移动、攻击指令偶尔丢一个,补一个新的就行,等确认就延迟了);
GPS 定位(实时传位置,晚一秒比丢一个坐标更要命)。
特殊情况:UDP 也能变 “靠谱”:
有些场景表面用 UDP,实际在应用层自己加了 “确认、重传” 机制(比如微信语音),相当于 “用 UDP 的壳,实现了 TCP 的功能”,兼顾速度和可靠性。
互动话题
你平时开发中用过 TCP 或 UDP 吗?是做文件传输、游戏还是其他场景?有没有遇到过 “TCP 太慢” 或 “UDP 丢包” 的问题?最后是怎么解决的?评论区说说你的经历,也聊聊你觉得哪种协议更难用好~
