BLE中的MTU:它是什么、包大小和协商

作者: IT Sectr 发布日期: 2026-07-15 阅读时间: 10 分钟

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应用程序性能的关键因素之一。

主要内容

  • MTU — 单个BLE包中的最大数据大小,从23字节(BLE 4.x)到251字节(BLE 5.0)。
  • MTU协商通过MTU Size Request/Response在建立GATT连接后进行。
  • 大MTU(247字节)可将数据传输速度提高5–10倍,与标准23字节相比。
  • Android自动请求MTU517字节(使用BLE 5.0),iOS通过requestMTU请求512字节。
  • 在OTA固件更新中,大MTU可将传输时间从分钟级缩短到秒级

什么是BLE中的MTU?

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协商:流程和协议

MTU Size Request — 由Central在建立GATT连接后发起的程序。Central发送MTU Request,指明其MTU容量(可接收的最大大小)。Peripheral以其自己的值回复MTU Response。使用的MTU是两个值中的较小者。如果Central建议MTU 512,而Peripheral仅支持128,连接将使用MTU 128。

swift
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限制:为什么MTU不能超过251字节

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最大DLEATT MTU限制
BLE 4.0 / 4.123字节27字节ATT固定
BLE 4.2247字节251字节257字节
BLE 5.0251字节251字节257字节
Android + iOS512 / 517251字节超过ATT

有趣的事实:iOS和Android分别请求MTU 512和517字节,但该值超过了ATT限制。实际上,BLE协议栈会自动磎片化这样的数据,将其作为多个最多251字节的顺序GATT请求发送。对于开发人员而言,差异是不可察觉的—writeValue在iOS中可以使用任何大小的数据,最大为512字节。

MTU对性能的影响

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和Android中配置MTU

iOS Core Bluetooth 在连接到Peripheral时自动协商MTU。开发人员可以通过maximumWriteValueLength检查当前MTU,但无法手动设置。iOS对BLE 5.0设备使用最大512字节的MTU,对BLE 4.2使用最大247字节。要写入大量数据,请使用writeType: .withResponse以确保发送。

kotlin
// 在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,在数据传输开始前完成,以避免在应用层进行磎片化。

MTU和OTA更新

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会怎样?

连接将使用默认MTU—23字节。对于大多数IoT场景(传输传感器读数)这已足够。对于大量数据的传输,速度将比协商后的MTU 247字节低5–10倍。

在数据传输开始后可以改变MTU吗?

不可以。MTU在连接后协啈一次,无法在不断开和重新连接的情况下改变。因此建议在发现服务后立即协商MTU,在活跃数据传输开始前完成。

为什么Android请求MTU 517字节而iOS只请求512字节?

这是每个协议栈历史上形成的经验最大值。实际的ATT MTU根据规范仍限制为257字节。协议栈会自动磎片化超过251字节的数据,因此512和517之间的差异可忽略不计。

MTU与Data Length Extension (DLE)如何关联?

MTU—ATT层面上GATT请求的大小。DLE—链路层物理包的大小。没有DLE,每个GATT请求(最多247字节)将被磎片化成27字节的包。使用DLE时,可在一个包中传输。要达到最大速度,两个参数都需要协商。

健身追踪器应该选择哪种MTU?

对于传输心率和步数的健身追踪器,标准MTU23字节就足够了。如果需要传输锻炼历史(大小10–50 KB),建议协商MTU 247字节,以加快与智能手机连接时的数据同步。

总结

  • MTU — 单个GATT请求中的最大数据大小:从23字节(默认)到251字节(BLE 5.0)。
  • MTU协商通过MTU Size Request/Response进行,由Central在连接后发起。
  • ATT协议将MTU限制为257字节,但iOS和Android通过自动磎片化请求最高512–517字节。
  • 将MTU从23字节提高到247字节可将带宽提高5–10倍(使用最佳连接间隔)。
  • 要达到最大速度,需要协啈MTU + DLE + connection interval 7.5 ms。
  • 在iOS中MTU自动协商,在Android中通过requestMtu实现,建议请求247–517字节。
  • OTA更新是要求最高的场景:正确的MTU可将传输时间从分钟级缩短到秒级

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读