通过蓝牙连接在iOS中调用close()会导致数据丢失

通过蓝牙连接在iOS中调用close()会导致数据丢失,ios,iphone,bluetooth,Ios,Iphone,Bluetooth,我们有一个通过蓝牙发送数据的应用程序,然后关闭连接 根本问题是在通过蓝牙发送所有数据之前调用close(),这会导致iOS不总是发送所有数据 这似乎是一个iOS问题。每次写入都是在最低的NSOutputStream级别成功完成的(我们甚至添加了代码来捕获每次写入后生成的事件,表示有更多的可用空间),但似乎iOS在某种程度上缓冲了内部事务,超出了我们的控制。当调用final close()时,根据时间的不同,iOS可能会丢弃挂起的数据,即使所有写入调用都返回了成功,并且收到了可用空间更多的关联事件

我们有一个通过蓝牙发送数据的应用程序,然后关闭连接

根本问题是在通过蓝牙发送所有数据之前调用close(),这会导致iOS不总是发送所有数据

这似乎是一个iOS问题。每次写入都是在最低的NSOutputStream级别成功完成的(我们甚至添加了代码来捕获每次写入后生成的事件,表示有更多的可用空间),但似乎iOS在某种程度上缓冲了内部事务,超出了我们的控制。当调用final close()时,根据时间的不同,iOS可能会丢弃挂起的数据,即使所有写入调用都返回了成功,并且收到了可用空间更多的关联事件。我一直在查看苹果公司关于易用性及其相关流的文档,但没有找到任何方法来确定iOS内部是否仍有悬而未决的数据

到目前为止,在close()之前添加一个对sleep()的调用任意数秒的粗略技巧可以消除这个问题,但所需的延迟实际上取决于发送的数据量和底层蓝牙传输的速度,因此,要事先知道延迟需要多少秒并不是一个简单的方法

我们还需要在连续写入之后添加延迟。使用20毫秒的值将失败,而使用200毫秒的值将成功,但会导致通信速度缓慢

(NSInteger) write:(NSData *)data error:(NSError **)error {
NSOutputStream *outputStream = [[Test_EADSessionController sharedController] getOutputStream];

if(m_isConnected == NO) {
                            [TestError setError:error withErrorCode:Test_ERROR_NO_CONNECTION];
                            return -1;
            }

            const void* dataAsBytes = [data bytes];
            NSInteger len = [data length];
            NSInteger bytesWritten = 0;
            while(bytesWritten <len){
    int maxTimeToWaitForSpaceAvailable = 2000 * 1000;

    while([outputStream hasSpaceAvailable] == NO && maxTimeToWaitForSpaceAvailable > 0) {
        usleep(100 * 1000);
        maxTimeToWaitForSpaceAvailable -= 100 * 1000;
    }

    NSInteger bytesToWrite = MIN(1024, len - bytesWritten);
    NSInteger tmp = [outputStream write:dataAsBytes + bytesWritten maxLength:bytesToWrite];

    usleep((int)([self timeToWaitAfterWriteInMilliseconds] * 1000));

                            if(tmp <= 0){
                                            bytesWritten = -1;
                                            [TestError setError:error withErrorCode:TEST_ERROR_WRITE_FAILURE];
                                            break;
                            }
                            bytesWritten += tmp;
            }
usleep((int)([self timeToWaitAfterWriteInMilliseconds] * 1000));
            return bytesWritten;
(NSInteger)写入:(NSData*)数据错误:(NSError**)错误{
NSOutputStream*outputStream=[[Test_EADSessionController sharedController]getOutputStream];
如果(m_未连接==否){
[测试错误设置错误:错误代码:测试错误没有连接];
返回-1;
}
const void*dataAsBytes=[数据字节];
NSInteger len=[数据长度];
NSInteger字节数=0;
while(字节写为0){
usleep(100*1000);
maxTimeToWaitForSpaceAvailable-=100*1000;
}
NSInteger bytesToWrite=MIN(1024,len-字节写入);
NSInteger tmp=[outputStream写入:dataAsBytes+BytesWrited maxLength:bytesToWrite];
usleep((int)([self timetowaitafterwriteinmillises]*1000));

如果(tmp我不确定什么是
Test\u EADSessionController
,你能从中发布相关代码吗?你对附件有控制权吗,这样它就可以用它接收到的每个数据块的校验和来回复?这将允许你检测它何时实际拥有数据并写入数据。它是一个围绕单个sess的单体包装器离子控制器。我们无法控制设备,使其返回校验和。