微信小程序 BLE 蓝牙数据包粘包

文章目录

    今天发现 Android 手机微信小程序中收到的 BLE 蓝牙数据包出现了粘包的情况。

    确认校验失败的数据包实际长度

    校验失败的数据包:

    • ab0002a20800a8ba ab0002a21a02b8ba ab0002a2
    • ab00022638100cba ab000628380bb80b b80bb8a5
    • ab000212380820ba ab00021338052cba ab000214

    长度均为 20 个字节(MTU 的默认大小,也是最小值); 02 包对应的长度为 8 个字节。

    单个包,以 ab 开始,ba 结束。可以看到明显的两个/甚至三个包的粘包现象。

    校验成功的

    • ab000423380c1c0b5450ba
    • ab00040b382710d8f028ba

    长度为 11 个字节

    猜测,当一个包的长度小于 10 字节时,会尝试向后面拼包。(实际不是这样,应该是高频引起的)

    被截断之后,后续数据并没有补发。

    根本原因:指令收发过快会有蓝牙粘包问题

    猜测是安卓系统在蓝牙接收数据的处理上有时间的设置。如果硬件发送给设备端的速度太快。前一个包可能会和后一个包粘连。

    例如接收 A,B,C。过快时会受到 A+B 前半段, B 后半段加 C 两个包。时序上没有错误。但包之间会粘连。包的数量也会变化。

    常用的解决方案:

    1. 限制 BLE 蓝牙设备的发送频率。
    2. 每个包固定大小为 20 字节,这样不会粘包
    3. 自定义协议上设置一个结束位,用于分割
    4. 先接收数据包,缓存,并拼接,然后集中处理

    粘包的英文

    packet fragmentation

    微信小程序获取 MTU 值

    https://developers.weixin.qq.com/miniprogram/dev/api/device/bluetooth-ble/wx.getBLEMTU.html

    • 小程序中 MTU 为 ATT_MTU,包含 Op-Code 和 Attribute Handle 的长度,实际可以传输的数据长度为 ATT_MTU - 3。例如 23, 实际数据长度为 20.
    • iOS 系统中 MTU 为固定值;安卓系统中,MTU 会在系统协商成功之后发生改变,建议使用 wx.onBLEMTUChange 监听。

    参考

    • http://events.jianshu.io/p/46daabc7787d

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式