0

我有一个项目,它连接到外部附件并与 iOS 应用程序进行少量数据通信。我能够像苹果在他们的 EADemo 参考代码中那样设置会话和流,并且一切似乎都运行良好。

我遇到的问题是,在使用该应用程序的随机时间后,输出流停止工作,但输入流仍然运行良好。我在每次写入尝试之前检查以确保 hasSpaceAvailable 为真,当我读回写入的字节数时,一切看起来都是正确的。此外,查看运行循环并不表示工作和非工作之间有任何区别,并且流状态仍然显示为打开。

我能看到的唯一导致这种情况的原因是我的附件没有连续确认应用程序的一些写入尝试,然后它就中断了。

我怎样才能检测到我处于这种状态,我该如何解决?

 // low level write method - write data to the accessory while there is space available and data to write
    - (void)_writeData {
        while (([[_session outputStream] hasSpaceAvailable]) && ([_dataToWrite length] > 0))
        {

            NSInteger bytesWritten = [[_session outputStream] write:[_dataToWrite bytes] maxLength:[_dataToWrite length]];

            if (bytesWritten == -1)
            {
                NSLog(@"write error");
                break;
            }
            else if (bytesWritten > 0)
            {
                [_dataToWrite replaceBytesInRange:NSMakeRange(0, bytesWritten) withBytes:NULL length:0];
            }
        }
    }

    // low level read method - read data while there is data and space available in the input buffer
    - (void)_readData {
        NSLog(@"reading data to buffer");
    #define EAD_INPUT_BUFFER_SIZE 128
        uint8_t buf[EAD_INPUT_BUFFER_SIZE];
        while ([[_session inputStream] hasBytesAvailable])
        {
            NSInteger bytesRead = [[_session inputStream] read:buf maxLength:EAD_INPUT_BUFFER_SIZE];
            if (_dataToRead == nil) {
                _dataToRead = [[NSMutableData alloc] init];
            }
            [_dataToRead appendBytes:(void *)buf length:bytesRead];
        }

        [[NSNotificationCenter defaultCenter] postNotificationName:EASessionDataReceivedNotification object:self userInfo:nil];
    }


    // high level write data method
    - (void)writeData:(NSData *)data
    {
     //   NSLog(@"writing data to buffer");
        if (_dataToWrite == nil) {
            _dataToWrite = [[NSMutableData alloc] init];
        }

        [_dataToWrite appendData:data];
        [self _writeData];


    }

// high level read method
- (NSData *)readData:(NSUInteger)bytesToRead
{
    NSLog(@"reading data");
    NSData *data = nil;
    if ([_dataToRead length] >= bytesToRead) {
        NSRange range = NSMakeRange(0, bytesToRead);
        data = [_dataToRead subdataWithRange:range];
        [_dataToRead replaceBytesInRange:range withBytes:NULL length:0];
    }
    return data;
}

    - (BOOL)openSession
    {
         NSLog(@"openSession");
        [_accessory setDelegate:self];

        if(_session){
            [self closeSession];
        }

        _session = [[EASession alloc] initWithAccessory:_accessory forProtocol:_protocolString];

        if (_session)
        {
            _runLoop = [NSRunLoop currentRunLoop];

            [[_session inputStream] setDelegate:self];
            [[_session inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [[_session inputStream] open];

            [[_session outputStream] setDelegate:self];
            [[_session outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [[_session outputStream] open];
            NSLog(@"creating session succeeded!");
        }
        else
        {
            NSLog(@"creating session failed!");
        }

        return (_session != nil);
    }
4

1 回答 1

0

我想我可能会遇到同样的问题。我有一个蓝牙连接的配件,当我测试范围时,我经常会遇到与您在问题中描述的完全相同的症状。

但是如何检测到问题是由附件未能 ACK 数据引起的呢?

我猜在我的情况下,附件正在发送 ACK,但是因为我处于蓝牙范围的边缘,所以我的手机永远不会收到 ACK。

现在我最好的选择是尝试在APP中检测情况。在我的情况下,我可以这样做,因为如果附件没有从手机接收任何数据,它将重新发送相同的包。因此,如果我多次看到从附件传输的相同数据,我将断开连接并要求用户靠近附件,然后重新连接。

于 2013-05-06T13:47:25.173 回答