iOS BLE 分包发送

作者: 离线0_0留言 | 来源:发表于2016-03-19 08:35 被阅读3092次
单次发送的数据过大,蓝牙模块内部接收缓冲区只有20个字节

BLE_SEND_MAX_LEN是蓝牙单次可处理最大字节长度

//分包发送蓝牙数据
-(void)sendMsgWithSubPackage:(NSData*)msgData 
                  Peripheral:(CBPeripheral*)peripheral
              Characteristic:(CBCharacteristic*)character
{
    for (int i = 0; i < [msgData length]; i += BLE_SEND_MAX_LEN) {
        // 预加 最大包长度,如果依然小于总数据长度,可以取最大包数据大小
        if ((i + BLE_SEND_MAX_LEN) < [msgData length]) {
            NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, BLE_SEND_MAX_LEN];
            NSData *subData = [msgData subdataWithRange:NSRangeFromString(rangeStr)];
            NSLog(@"%@",subData);
            [self writeCharacteristic:peripheral
                       characteristic:character
                                value:subData];
            //根据接收模块的处理能力做相应延时
            usleep(20 * 1000);
        }
        else {
            NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, (int)([msgData length] - i)];
            NSData *subData = [msgData subdataWithRange:NSRangeFromString(rangeStr)];
            [self writeCharacteristic:peripheral
                       characteristic:character
                                value:subData];
            usleep(20 * 1000);
        }
    }
}

相关文章

网友评论

  • CathyLiu1213:ios得分包传输,但是安卓那边不用,这是什么原因,ios这边分包传输会导致穿入的数据如果是图片格式,会出现乱码,这是什么原因导致的
  • 花蕊1235:请问,接收蓝牙外设扫描到的数据,怎么分包接受,而且不知道分几个包??求解答。谢谢
  • Noah_bin:楼主你的[self writeCharacteristic:peripheral
    characteristic:character
    value:subData]; 这个是哪个方法??
    花蕊1235:请问,接收蓝牙外设扫描到的数据,怎么分包接受,而且不知道分几个包??求解答。谢谢
    离线0_0留言:就是系统的蓝牙方法重写了 第一个参数名错了 应该是peripheral
  • 迷恋代码:我们公司低功耗最大的分包数是127,我发送的数据是30000左右,要花13秒的时间,没办法接受
  • naiyi:最核心的点不是应该体现出来这是writeWithoutResponse吗。。。
    而且iOS本身就是有流控的,连续多少次writeValue都没有关系,BTServer进程会接管并暂存缓冲数据做RF流控,虽然不清楚其缓冲区具体能做多大的流控,但我至今还没遇到过BTServer的缓冲区溢出造成writeValue被丢弃的情况。
    如果仅仅是顾虑外设的应用层对数据的处理速度不足以支撑RF层接收数据的速度,从而造成HCI缓冲区溢出丢包,那何不实测外设的应用层处理速度然后增加射频的连接间隔以达到负载均衡的目的,这岂不是比手机应用层在sleep,而蓝牙射频持续发空包保持连接要合理的多?
    naiyi:另外,我觉得手动分包只对流媒体这种无间断的流数据有意义。
    如果数据是完整单元(就是说有确定的开始和结束边界,比如一个zip压缩包或者一个txt文件),那么即使writeValue的数据量大于20字节也是没必要手动分包的。
    CoreBlueTooth会自动根据writeValue中的NSData字节长度与ATT_MTU-3来做比较,超过MTU的话会在L2CAP层采用writeLongValue协议发送,即在数据报文的报头中通过标记逻辑链路标识符10(开始包)和01(延续包)的方式来发送。
    而在外设中通过prepareWrite Event来进行延续包的缓存直到发现下一个开始包(包括空的开始包在内)为止,触发executeWrite Event来结束这个长数据包的接收。
    也就是说外设应用层根据事件类型就可以区分多次传输组成整包的开始和结束,并在结束后进行一次性处理执行,没有必要给业务数据增加额外的边界标示并手动分包。
    当然这样的话需要嵌入式工程师配合调整固件程序以支持writeLongValue,但我觉得这个方式比校验额外添加的边界再手工组包要简单和直白的多。
    naiyi:@离线0_0留言 您所指的多次失败和多几秒的等待是什么?在我看来,把连接间隔适配到外设mcu在应用层处理能力的范围内,可以减少无效的射频的功耗开销。而其他效果跟app的应用层sleep是没什么区别的,无非是需要发送的数据暂存在app进程还是BTServer进程。如果RF的发送速率高于外设应用层处理能力,那无论是sleep方案还是增加连接间隔方案都依然不可避免的在HCI层丢包。
    离线0_0留言:此方法确实只在应用层做文章 也满足一般用户需求
    从性能来说 可以通过修改波特率等方法来用好每一秒射频连接
    但是对用户来说 本就是几十字节的内容 多次失败和多几秒的等待
    哪个体验更好呢
  • 6e2c5a8150c5:2017-07-05 17:17:44.148 BabyBluetoothAppDemo[469:96293] 60
    2017-07-05 17:17:44.149 BabyBluetoothAppDemo[469:96293] subData=<00007461 696c756f 7761>
    2017-07-05 17:17:44.149 BabyBluetoothAppDemo[469:96293] 发送msg =
    2017-07-05 17:17:44.171 BabyBluetoothAppDemo[469:96293] 70
    2017-07-05 17:17:44.171 BabyBluetoothAppDemo[469:96293] subData=<6e675459 45520000 0005>
    2017-07-05 17:17:44.172 BabyBluetoothAppDemo[469:96293] 发送msg = ngTYER
    2017-07-05 17:17:44.193 BabyBluetoothAppDemo[469:96293] 80
    2017-07-05 17:17:44.194 BabyBluetoothAppDemo[469:96293] subData=<00000032 30313254 5045>
    2017-07-05 17:17:44.194 BabyBluetoothAppDemo[469:96293] 发送msg =
    2017-07-05 17:17:44.216 BabyBluetoothAppDemo[469:96293] 90
    2017-07-05 17:17:44.217 BabyBluetoothAppDemo[469:96293] subData=<31000000 0b000000 7461>
    2017-07-05 17:17:44.217 BabyBluetoothAppDemo[469:96293] 发送msg = 1
    2017-07-05 17:17:44.239 BabyBluetoothAppDemo[469:96293] 100
    2017-07-05 17:17:44.240 BabyBluetoothAppDemo[469:96293] subData=<696c756f 77616e67 0000>
    2017-07-05 17:17:44.240 BabyBluetoothAppDemo[469:96293] 发送msg = iluowang
    2017-07-05 17:17:44.262 BabyBluetoothAppDemo[469:96293] 110
    2017-07-05 17:17:44.262 BabyBluetoothAppDemo[469:96293] subData=<00000000 00000000 0000>
    2017-07-05 17:17:44.262 BabyBluetoothAppDemo[469:96293] 发送msg =
    这中间msg= 后面没有数据,打印subData 也都是0 这种情况怎么处理,我现在是用两个手机,一个中心,一个外设,传输一段MP3的听力文件
  • Luke0407:太感谢楼主了,已经成功了
    6e2c5a8150c5:@离线0_0留言 这个10字节是我自己写的,我现在只是做一个demo,用俩手机,一个中心,一个外设,想实现一段MP3听力文件的传输,但是总是分割的subData 是<00000000 00000000 0000>这个,并且将subData传过去之前转换成string 也是 空,是不是听力文件中间停顿本身就没有声音的缘故?
    离线0_0留言:@123_9bfd 蓝牙模块单次接收能力就只有10字节 那就以10字节为单位分包
    6e2c5a8150c5:大神,有木有传输听力MP3文件成功并且避免丢包的demo?我这边现在每次传10字节,出现了丢包的情况,而且每次丢包都在同一个地方,这个是什么原因呢?
  • ice清凉:楼主请问有没有做过录音的传输, 传输数据过后拼接数据怎样做呢?
    离线0_0留言:@Y了个坤 这应该是硬件工程师给出接口协议的,当然如果是在dump那就另说了
    彦子凡:楼主,我的硬件有两个UUID,一个是启动还开始写数据,一个是直接用来写数据,怎么根据返回来判断
    离线0_0留言:@ice清凉 看后台数据接口,可以直传文件或者转为数据流,大文件考虑加入断点续传
  • IOS_绿豆糕:楼主 如果是接收的话 怎么解析分包数据 拼起来?
    离线0_0留言:@IOS_绿豆糕 我做的蓝牙硬件是直接接收数据,自行识别有效数据段,执行数据段指令,也就是说在外设的软件层对数据进行接收后分段。那么手机端同理,主要看你的指令规则
    IOS_绿豆糕:收 和 发
    离线0_0留言:@IOS_绿豆糕 手机作为中心接受数据?
  • ee52c78882b3:你好 我的项目中 有分包 每20字节延时5ms 发送数据6000字节+ 总时间5s左右 有没有办法在压缩一下时间 还是感觉时间有点长 安卓的有分包 没延时 但是iOS 不延时的话 丢包很严重啊 安卓为什么 没有这种情况呢
    CathyLiu1213:ios得分包传输,但是安卓那边不用,这是什么原因,ios这边分包传输会导致穿入的数据如果是图片格式,会出现乱码
    离线0_0留言:@ee52c78882b3 分包发送的丢包问题是看外设的处理能力,受限点不在发送端,可以问下安卓组的延时时间,然后这么大的数据量,可以考虑本身数据源是否有精简的可能,比如一些重复的信息和字段

本文标题:iOS BLE 分包发送

本文链接:https://www.haomeiwen.com/subject/rofhlttx.html