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

更新日期: 2023-02-28 阅读次数: 2041 字数: 503 分类: 物联网

今天发现 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 聊聊, 查看更多联系方式