2011-06-29 50 views
1

我在使用外部附件框架连接到蓝牙配件时遇到延迟问题。当发送数据时,我得到在控制台下面的自定义输出:如何让NSOutputStream立即发送或刷新数据包

if([stream hasSpaceAvailable]) 
{ 
    NSLog(@"Space avail"); 
} 
else { 
    NSLog(@"No space"); 
} 
while([stream hasSpaceAvailable] && ([_outputBuffer length] > 0)) 
{ 
    /* write as many bytes as possible */ 
    NSInteger written = [stream write:[_outputBuffer bytes] maxLength:[_outputBuffer length]]; 
    NSLog(@"wrote %i out of %i bytes to the stream", written, [_outputBuffer length]); 
if(written == -1) 
    { 
     /* error, bad */ 
     Log(@"Error writing bytes"); 
     break; 
    } 
    else if(written > 0) 
    { 
     /* remove the bytes from the buffer that were written */ 
     Log(@"erasing %i bytes", written); 
     [_outputBuffer replaceBytesInRange:NSMakeRange(0, written) withBytes:nil length:0 ]; 
    } 
} 

这将导致用下面的输出,其中直接包缓冲区的有效载荷。

immediate pack buffer-> 040040008 
Space avail 
wrote 10 out of 10 bytes to the stream 
immediate pack buffer-> 040010005 
No space 
immediate pack buffer-> 030040007 
No space 
wrote 20 out of 20 bytes to the stream 
immediate pack buffer-> 030010004 
No space 
immediate pack buffer-> 040000004 
Space avail 
wrote 20 out of 20 bytes to the stream 
immediate pack buffer-> 030000003 
Space avail 
wrote 10 out of 10 bytes to the stream 
immediate pack buffer-> 040040008 
Space avail 
wrote 10 out of 10 bytes to the stream 

注意它是如何不断地有“没有空间”写这意味着该方法hasSpaceAvailable是返回false,并迫使数据进行缓冲,直到它返回true。

1)我需要知道的是为什么会发生?它是否在等待BT硬件的Ack?如果是的话,你如何消除这种阻塞?

2)你如何做到这一点,所以它立即发送,我们基本上实时流数据没有缓冲?

3)是否有隐藏的API方法将禁用此阻止?

这是一个真正的问题,因为发送数据到设备不会有任何延迟/延迟,必须立即发送,以便硬件与iPhone命令同步。请帮忙。

回答

2

对于大多数硬件(在开始下一个数据包之前将完成发送当前数据包),您所要求的是不可能的,并且不可能使用通常的“数据流”模式(这要求按顺序接收数据是带宽受限的)。

除非源和目标重合,否则零延迟也是物理上不可能的。

实际问题似乎是底层数据流一次只排队一个数据包,即使数据包只有10个字节长。我不知道为什么;可能是因为它的目的是作为一个非常简单的协议。

处理这样一个队列的通常方式是注册适当的委托回调,并发送尽可能多的数据,因为当数据流有可用空间时,而不是等待下次尝试发送数据时似乎是你在做什么)。

0

问题是HandleEvent委托函数是一个异步调用。所以每次它都没有碰到委托。 你可以做的是,让数组中的命令集合一次,打开会话,调用writeData函数。这里发生的是,一旦写入数据被调用,你不需要HandleEvent函数被击中为每个命令。 在writeData函数中为count数组项计数递增计数,直到count == arrayItems,Delegate未被命中。

因此,列表中的所有命令都是逐个发送的。

-1

我面临同样的问题,但在不同的情况。

场景:iPhone应用程序能够在第一次连接时与PED进行通信。但是,当PED电池电量耗尽或关闭后再打开时,尽管有活动会话和有效输出流,但应用程序无法与PED通信。输出蒸汽说它没有写任何东西。

解决方案:当PED切换时,应用程序会收到通知,此时我会让应用程序终止EASession,并在PED获取连接时再次创建该应用程序。不确定是否是最佳解决方案。如果有的话,请提出另一种解决方案。

相关问题