MTU (Maximum Transmission Unit) 是在一次GATT交易中可以在设备之间传输的单个BLE包中有用数据的最大大小。在BLE Classic (4.x)中,MTU固定为23字节,足以应付小型传感器读数,但无法满足文件传输或OTA更新的需要。Bluetooth Core Specification 4.2 (2014)引入了MTU Size Request程序,允许协商更大的MTU — 最高达247字节(BLE 5.0 — 最高达251字节)。正确配置MTU是传输大量数据的BLE应用程序性能的关键因素之一。
主要内容
Maximum Transmission Unit (MTU) 在BLE背景下,是设备在一个GATT请求中可以接收的最大Application Protocol Data Unit (APDU)。MTU在ATT(Attribute Protocol)层面上定义,包含ATT头部(1字节)+ 有用数据。默认情况下,所有BLE设备都支持23字节的MTU(23 = 1字节ATT头部 + 22字节数据)。
MTU不是无线电频道的物理限制,而是GATT层面上设备之间的协议。BLE包在链路层(Link Layer)的物理大小可以更大(BLE 4.0中最高27字节,BLE 5.0中使用Data Length Extension可达257字节),但GATT层面限制了每次交易中传输的数据量。Data Length Extension (DLE)是链路层的一个独立机制,可将物理包增大到251字节,并需要单独协商。
MTU和DLE之间的区别:ATT MTU—每个GATT请求中传输的数据量;DLE—每个链路层包中可容纳的数据量。要达到最大速度,两个参数都需要协商。没有DLE,即使MTU为247字节,数据也将被磎片化成多个27字节的链路层包,从而降低带宽。
MTU Size Request — 由Central在建立GATT连接后发起的程序。Central发送MTU Request,指明其MTU容量(可接收的最大大小)。Peripheral以其自己的值回复MTU Response。使用的MTU是两个值中的较小者。如果Central建议MTU 512,而Peripheral仅支持128,连接将使用MTU 128。
import CoreBluetooth
// 在iOS上请求最大MTU
func requestMTU(central: CBCentralManager,
peripheral: CBPeripheral) {
peripheral.maximumWriteValueLength(
for: .withoutResponse
)
// iOS在连接时自动协商MTU
// BLE 5.0设备的MTU = 512
let mtu = peripheral.maximumWriteValueLength(
for: .withResponse
)
print("已协商的MTU:" +
String(mtu))
}
协商时机:MTU Request应在发现服务(discoverServices)后、活跃数据传输开始前发送。在iOS中,Core Bluetooth在连接时自动协商MTU—开发人员无需手动发送MTU Request。在Android中,需要显式调用requestMTU。协商后,MTU对该连接保持固定—没有断开和重新连接就无法重新协商。
ATT (Attribute Protocol) — GATT构建在其上的协议。ATT包的最大大小为257字节(ATT_MTU-1)。其中1字节为Opcode(操作类型),1字节为Handle,最多255字节为Value。因此,ATT规范允许的最大MTU为257字节(实际中使用最多251字节,因为一些服务字段仍然是必要的)。
为了发送大于MTU的数据,在应用层使用磎片化。开发人员自行将数据分割成大小≤ MTU的块,并顺序发送。每个块正式上是一个独立的GATT Write Request请求。接收方将块组装成一个缓冲区。GATT中没有内置的磎片化支持—这是开发人员的任务。
| BLE版本 | 最大MTU | 最大DLE | ATT MTU限制 |
|---|---|---|---|
| BLE 4.0 / 4.1 | 23字节 | 27字节 | ATT固定 |
| BLE 4.2 | 247字节 | 251字节 | 257字节 |
| BLE 5.0 | 251字节 | 251字节 | 257字节 |
| Android + iOS | 512 / 517 | 251字节 | 超过ATT |
有趣的事实:iOS和Android分别请求MTU 512和517字节,但该值超过了ATT限制。实际上,BLE协议栈会自动磎片化这样的数据,将其作为多个最多251字节的顺序GATT请求发送。对于开发人员而言,差异是不可察觉的—writeValue在iOS中可以使用任何大小的数据,最大为512字节。
MTU大小直接影响BLE连接的带宽。在MTU为23字节时,理想条件下的最大有用传输速度约为7–10 KB/s。将MTU增加到247字节可将速度提升到60–90 KB/s(配合DLE和最佳连接间隔)。这对于传输图像、音频片段或日志的应用程序尤为重要。
BLE传输性能取决于三个因素:MTU(每个ATT请求中的数据量)、connection interval(交换事件发生的频率)和DLE(每个链路层包中的数据量)。最大速度的最佳配置为:MTU = 247,DLE = 251,connection interval = 7.5 ms(最小值)。
根据Bluetooth SIG White Paper (2023)的数据,在30 ms的连接间隔下,将MTU从23字节提高到247字节可使带宽从8 KB/s提升到42 KB/s,提升了5倍。在7.5 ms的连接间隔下,带宽可达到88 KB/s。对于不需要高速的应用(如温度传感器、BLE信标),标准23字节的MTU仍然足够。
iOS Core Bluetooth 在连接到Peripheral时自动协商MTU。开发人员可以通过maximumWriteValueLength检查当前MTU,但无法手动设置。iOS对BLE 5.0设备使用最大512字节的MTU,对BLE 4.2使用最大247字节。要写入大量数据,请使用writeType: .withResponse以确保发送。
// 在Android上请求MTU(Kotlin)
val bluetoothGatt: BluetoothGatt = ...
// 请求MTU 517字节
bluetoothGatt.requestMtu(517)
// 在回调中处理结果
override fun onMtuChanged(
gatt: BluetoothGatt,
mtu: Int,
status: Int
) {
if (status == BluetoothGatt.GATT_SUCCESS) {
println("MTU negotiated: $mtu")
}
}
Android 提供了BluetoothGatt.requestMtu(int),允许请求任何最高517字节的MTU。实际MTU由外围设备决定—如果它仅支持23字节,Android将返回MTU 23。要确定当前MTU,请使用gatt.requestMtu(0)—它将返回当前值,不会尝试更改。Android 12+通过TRANSPORT_LE支持在连接时自动协商MTU。
跨平台框架(Flutter、React Native)通常提供用于requestMTU的API。在FlutterBlue Plus库中,MTU作为连接参数设置。在RxAndroidBle中—通过requestMtu方法。建议始终在发现服务后立即协商最大MTU,在数据传输开始前完成,以避免在应用层进行磎片化。
OTA(空中下载)固件更新 — BLE中对MTU要求最高的场景。IoT设备固件的典型大小为100–500 KB。在MTU为23字节、连接间隔为30 ms时,传输100 KB大约需要2–3分钟。在MTU为247字节、DLE为251字节时—20–40秒。而在MTU为512字节(iOS)时—10–15秒。
OTA更新过程通常包括:将固件磎片化成大小≤ MTU的包,通过Notify/Write顺序发送,验证每个包的校验和并确认接收。如果某个包丢失,设备会请求重新发送。OTA的可靠性彻底取决于MTU和连接间隔的正确选择。
OTA建议:协商最大MTU(247–512字节),将连接间隔设置为7.5–15 ms(如果设备支持),使用DLE(Data Length Extension)将物理包增大到251字节。对于具有有限缓冲内存的设备(例如基于nRF52的BLE模块),请在芯片规格中检查最大MTU。
常见问题
连接将使用默认MTU—23字节。对于大多数IoT场景(传输传感器读数)这已足够。对于大量数据的传输,速度将比协商后的MTU 247字节低5–10倍。
不可以。MTU在连接后协啈一次,无法在不断开和重新连接的情况下改变。因此建议在发现服务后立即协商MTU,在活跃数据传输开始前完成。
这是每个协议栈历史上形成的经验最大值。实际的ATT MTU根据规范仍限制为257字节。协议栈会自动磎片化超过251字节的数据,因此512和517之间的差异可忽略不计。
MTU—ATT层面上GATT请求的大小。DLE—链路层物理包的大小。没有DLE,每个GATT请求(最多247字节)将被磎片化成27字节的包。使用DLE时,可在一个包中传输。要达到最大速度,两个参数都需要协商。
对于传输心率和步数的健身追踪器,标准MTU23字节就足够了。如果需要传输锻炼历史(大小10–50 KB),建议协商MTU 247字节,以加快与智能手机连接时的数据同步。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。