为什么裸TCP发数据比较笨
TCP、WebSocket、MQTT 协议设计理解总结
1. TCP 直接传递消息为什么比较麻烦?
TCP 提供的是:
可靠的字节流(Byte Stream)
而不是:
消息流(Message Stream)
TCP 只保证:
- 字节顺序一致
- 数据可靠到达
- 数据不丢失
但是 TCP 不知道消息边界。
例如:
发送端:
send("hello");
send("world");
发送方认为:
hello
world
是两条消息。
但是接收端:
recv()
可能得到:
情况1:
hello
情况2:
helloworld
情况3:
hel
loworld
以上情况 TCP 都认为正常。
因为 TCP 只负责传输:
字节 字节 字节 字节
它不知道:
hello 是一条消息
world 是另一条消息
2. 裸 TCP 通信需要自己设计协议
如果直接使用 TCP 做应用通信,需要自己解决:
- 消息边界
- 分包
- 粘包
- 消息长度
- 消息类型
- 数据解析
例如设计:
+--------+--------+----------+
| length | type | payload |
+--------+--------+----------+
数据:
00 10 1001 OPEN_LIGHT
接收流程:
读取 length
|
读取完整 payload
|
解析 type
|
执行业务
这就是很多设备协议、工业协议、游戏协议的设计方式。
本质:
TCP
+
自定义应用协议
3. WebSocket 解决 TCP 的消息边界问题
WebSocket 可以理解为:
在 TCP 可靠字节流之上增加了一层消息协议。
协议层:
业务数据
↑
WebSocket Frame
↑
TCP
↑
IP
WebSocket Frame 已经定义:
- opcode(消息类型)
- length(消息长度)
- payload(数据)
所以:
发送:
message1
message2
接收:
frame1
frame2
应用层不需要自己处理:
- TCP 粘包
- TCP 拆包
- 消息边界
因此:
TCP:
字节流
WebSocket:
消息流
4. WebSocket 和 TCP 的区别
TCP:
解决:
两端可靠传输字节
WebSocket:
解决:
两端以消息为单位进行通信
TCP 不知道:
这是一条消息
WebSocket 知道:
这是一个完整 Frame
5. 为什么简单消息系统适合 WebSocket?
适合:
- 聊天
- 推送
- 控制命令
- 设备控制
- 后台实时通知
- 简单游戏
架构:
客户端
|
WebSocket
|
服务器
特点:
- 长连接
- 双向通信
- 消息边界明确
- 开发简单
6. 为什么大型实时游戏通常不用 WebSocket?
简单游戏可以:
例如:
- 棋牌
- 回合制游戏
- 社交游戏
可以:
客户端
|
WebSocket
|
服务器
但是大型实时游戏,例如 FPS:
需要:
- 极低延迟
- 高频状态同步
- 丢包可接受
- 自定义可靠机制
例如:
玩家位置:
100ms 前的位置丢失没有关系
因为最新状态更重要。
通常使用:
UDP
+
自定义游戏协议
或者:
QUIC
原因:
WebSocket 基于 TCP。
TCP 特性:
可靠
有序
但是:
如果一个数据包丢失:
packet1 丢失
TCP等待重传
packet2
packet3
必须等待
这叫:
队头阻塞(Head-of-Line Blocking)
对于实时游戏:
等待旧数据恢复反而降低体验。
7. MQTT 在 WebSocket 基础上的进一步抽象
WebSocket:
解决:
消息怎么传输
MQTT:
解决:
消息如何流转
WebSocket:
A <----------> B
是端到端通信。
MQTT:
Broker
/ | \
A B C
引入:
- Broker
- Topic
- Publish
- Subscribe
例如:
设备发布:
topic:
home/light/status
payload:
ON
手机订阅:
home/light/status
Broker 自动完成:
消息匹配
消息转发
多端分发
8. 协议选择总结
普通消息通信
特点:
- 消息量不大
- 关注实时推送
- 需要双向通信
适合:
WebSocket
MQTT
HTTP/2
高可靠业务协议
特点:
- 强一致
- 事务
- 固定领域语义
例如:
- 支付
- 数据库
- 工业控制
适合:
TCP + 自定义协议
或者:
HTTP
MQTT
实时流协议
特点:
- 连续数据
- 低延迟
- 可以接受部分丢失
例如:
- 视频
- 音频
- 实时游戏状态
适合:
UDP
RTP
QUIC
WebRTC
9. 核心思想总结
网络协议设计本质:
底层协议越通用,上层越需要补充业务语义。
分层理解:
TCP
提供:
可靠字节传输
↓
WebSocket
增加:
消息边界
↓
MQTT
增加:
消息模型和流转机制
最终:
- TCP 解决数据怎么可靠到达
- WebSocket 解决数据如何成为消息
- MQTT 解决消息如何在多个设备之间流转
不同协议不是互相替代,而是在不同层次解决不同问题。
浙公网安备 33010602011771号