我正在开发一个需要在iPhone和设备之间发送大量数据的应用程序(发送数据大约需要10秒钟)。但我希望能够随时取消数据通信。我知道我可以随时使用
删除与设备的连接centralManager.cancelPeripheral(peripheral)
但这不是我真正想要的,因为我想停止发送数据,但没有终止蓝牙连接。
有没有办法在不断开与设备的连接的情况下终止数据传输?
发送数据的代码如下:
for (var Hex: UInt8 = 0x01; Hex <= 0x14; Hex+=1){
var outbuffer = [UInt8](count: 16, repeatedValue: 0x00)
outbuffer[0] = (0x68)
outbuffer[1] = (Hex)
let data = NSData(bytes: outbuffer, length: 7)
print("data\(data)")
connectingPeripheral.writeValue(data, forCharacteristic: connectingCharacteristicPassword , type: CBCharacteristicWriteType.WithResponse)
}
答案 0 :(得分:1)
我认为我会继续并就此提出意见。 CoreBluetooth无法停止已经写入输出缓冲区的数据包的传输。造成这种情况的原因仅仅是因为它不需要而且它将是一种无用的功能。你遇到这个问题的唯一原因是因为我认为你的方法是错误的。不要将所有内容都放在for循环中并立即推送数据。相反,你应该实现某种流量控制机制。
在蓝牙LE中,有两种主要方式将数据写入外设:“写命令”和“写请求”。你可以看一下TCP和UDP协议。使用write命令,您只需发送数据,而无需知道蓝牙链接另一端的应用程序是否接收到数据。对于写入请求,您正在发送数据并让外围设备知道您希望得到通知(确认)数据实际上已被接收。这两种类型在CoreBluetooth中称为 CBCharacteristicWriteWithResponse 和 CBCharacteristicWriteWithoutResponse 。使用 CBCharacteristicWriteWithResponse 编写数据时(就像在代码中一样),您将获得外设:didWriteValueForCharacteristic:error:回调,用于验证数据是否已到达另一个侧。此时,您现在可以选择继续并根据需要发送下一个数据包,但如果您出于某种原因想要停止发送数据,那么您也可以这样做。这样做可以控制整个流程,而不仅仅是通过for循环推送所有内容。
但是等等,为什么你会想要使用写命令呢?好吧,由于写请求要求接收方回应发送方,这意味着必须在两个方向上发送数据。在这种情况下,由于ack是由应用层发送的,因此必须等待下一个连接间隔才能发送ack。这意味着当发送大量数据时,每两个连接间隔只能发送一个数据包,这将使您的整体比特率非常差。
使用write命令,因为它们没有被激活,你可以在一个连接事件窗口中发送尽可能多的manny数据包。在大多数情况下,您应该能够在每个连接窗口发送大约10-20个数据包。但请注意,如果您发送的数据包过多,则会填充传出缓冲区,数据包将丢失。因此,您可以尝试的是使用 WriteWithoutResponse 类型直接发送9个数据包,然后发送 WriteWithResponse 类型的1个数据包。执行此操作后,您可以等待 peripheral:didWriteValueForCharacteristic:error:回调,然后您可以以相同的方式再发送10个数据包。这样,您将设法每2个连接间隔发送10个数据包,同时仍能更好地控制流量。
您当然可以尝试一下这个比例,但请记住缓冲区是在iOS设备上的多个应用程序之间共享的,因此您不希望太接近限制。