在做手机 / 前端 / 小程序 与 BLE 设备通信时,很多人都会遇到这些疑问:
为什么 BLE 一次只能传20 字节?
JSON 为什么一用就超限?
MTU 到底是什么,调了有什么用?
ATT、GATT 老是一起出现,它们到底有什么区别?
如果你也被这些问题绕晕过,这篇文章就是为你准备的。本文会用尽量通俗、工程视角,把这些概念一次讲清楚。
一、先给结论(让你心里有个数)
在不做任何额外配置的情况下:
BLE单次稳定可传输数据:20 字节
原因不是手机、不是代码,而是底层协议限制
在BLE 4.2+ 并成功协商 MTU的情况下:
单包常见最大有效数据:244 字节
但依然不适合大 JSON,只是“缓解”,不是“解决”
这些限制,都和 ATT、GATT、MTU 有关。
二、BLE 为什么不能像 HTTP / Socket 那样随便传?
因为 BLE 的设计目标就不是“高速大数据传输”,而是:
低功耗
低速
设备简单
所以 BLE 在协议设计上:
数据包很小
规则很严格
强调“短、快、结构化”
这也是为什么:
BLE 非常不适合直接传 JSON 文本
三、ATT 是什么?(真正限制你的东西)
1️⃣ ATT 的全称
ATT(Attribute Protocol),中文一般叫:
属性协议
一句话理解:
ATT 规定了 BLE 里“数据怎么读、怎么写、一次能传多少”
2️⃣ ATT 的核心思想:一切都是 Attribute
在 ATT 看来,设备里的所有数据都是一条条Attribute(属性):
每条 Attribute 都有一个编号(Handle)
一个类型(UUID)
一个值(Value)
以及访问权限
ATT 不关心:
你传的是不是 JSON
是不是字符串
代表什么业务含义
它只关心一件事:
这个包装不装得下?
3️⃣ 为什么默认只能传 20 字节?
关键点来了 👇
ATT 有一个概念:ATT MTU
默认ATT MTU = 23 字节
其中3 字节是协议本身的开销
所以:
23 - 3 = 20 字节
👉 这就是“BLE 单包 20 字节限制”的真正来源。
四、MTU 是什么?为什么能变成 244 字节?
1️⃣ MTU 的含义
MTU(Maximum Transmission Unit):
一次数据包允许承载的最大字节数
在 BLE 里,说的通常是ATT MTU。
2️⃣ MTU 协商(BLE 4.2+)
从 BLE 4.2 开始:
手机和设备可以协商 MTU
双方各报一个最大值
最终取两者的最小值
常见情况:
| MTU | 实际可用数据 |
|---|---|
| 23 | 20 |
| 64 | 61 |
| 128 | 125 |
| 247 | 244 |
👉 所以大家常说:
BLE 常见最大单包有效数据是 244 字节
但前提是:
手机支持
设备支持
协商成功
五、GATT 是什么?(你真正“在用”的东西)
如果只有 ATT,会有一个问题:
“我读到一条数据,但它代表什么?”
于是就有了GATT。
1️⃣ GATT 的全称
GATT(Generic Attribute Profile):
通用属性规范
它不是传输协议,而是:
规定 Attribute 应该如何组织、如何被使用
2️⃣ GATT 引入的核心概念
GATT 在 ATT 之上,定义了:
Service(服务):一组相关数据
Characteristic(特征):真正存数据的地方
Descriptor(描述符):对特征的补充说明
你在代码里操作的:
serviceIdcharacteristicId
👉 都是GATT 概念。
3️⃣ 一个直观对比
同一条数据:
在ATT眼里:
一段二进制值
六、ATT 和 GATT 的核心区别(一定要分清)
| 对比点 | ATT | GATT |
| 层级 | 底层 | 上层 |
| 作用 | 怎么传数据 | 数据怎么组织 |
| 是否限制 20 字节 | ✅ 是 | ❌ 否 |
| 是否懂业务 | ❌ 不懂 | ✅ 懂 |
| 你是否直接操作 | ❌ | ✅ |
一句话总结:
你操作的是 GATT,但真正限制你的是 ATT。
七、为什么 BLE 不推荐直接用 JSON?
1️⃣ JSON 天生“占字节”
{"cmd":"open","time":123456}
字段名多
字符多
冗余高
在 20 字节限制下,非常容易超。
2️⃣ 必然带来的问题
拆包 / 分包
包序号
重组逻辑
出错处理
👉 复杂度直线上升。
3️⃣ BLE 更推荐的做法
二进制协议
命令字 + 参数
固定长度或简单结构
例如:
[0x01, 0x58]
而不是 JSON 文本。
八、把所有关系串起来(很重要)
真实的数据流是这样的:
你的业务数据
↓
GATT(服务 / 特征)
↓
ATT(读 / 写 / 通知,受 MTU 限制)
↓
底层蓝牙链路
所以:
20 字节问题 →ATT + MTU
服务 / 特征 →GATT
JSON 是否合适 →协议设计问题
九、一句话终极总结
ATT 是 BLE 的“运输层”,决定一次能传多少、怎么传;
GATT 是 BLE 的“数据使用规范”,决定数据如何组织、如何被理解。
默认 ATT MTU 为 23 字节,导致单包有效数据只有 20 字节;
BLE 4.2+ 可通过 MTU 协商提升到常见的 244 字节,但 BLE 依然更适合短小、结构化的数据,而不是直接传 JSON。