我正在开发一款用于控制物理硬件的iPhone应用程序 例程如下:
该例程通常有效。但是,我常常在接收时遇到无法解释的UDP包丢失;也就是说,我发送8字节"唤醒"信号,但我没有得到94字节的响应。 当应用程序工作时,它完美地工作:我几乎没有丢失一个包,如果应用程序错过了第一个94字节的消息,它将获得第二个或第三个消息。 当它不起作用时,它会不断地错过所有包裹。 "不工作"阶段可能持续数分钟或数小时;我发现没有明显的触发因素 - 好像在某个阶段,没有任何理由,接收停止工作。
在问这里之前,我做了非常广泛的调试。我通过rvictl和tcpdump监视了套接字,并确认我的日志反映了套接字级别发生的情况。 为了使外部硬件脱离等式,我构建了一个与硬件一样的镜像应用程序。我尝试过更换端口,我试图关闭并单独插入套接字,重置它们,暂停并重新启动接收。这些都不起作用。
我用GCDAsyncUdpSocket开发了我的通讯库。为了安全起见,我还尝试了非GCD版本;结果是一样的。我在C套接字周围构建了自己的最小包装器;我有同样的行为。
这是我的实施代码:
GCDAsyncUdpSocket *udpSocket;
- (void)startUdpBroadcast {
if (udpSocket == nil)
{
// Setup our socket.
udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
[udpSocket setIPv6Enabled:NO];
}
NSLog(@"Listening for a message on %@",[self getBroadcastAddress]);
NSError *bindError = nil;
NSError *enableError = nil;
NSError *receivingError = nil;
[udpSocket bindToPort:8089 error:&bindError];
if (bindError) {
NSLog(@"Error, can't bind: %@",[bindError localizedDescription]);
return;
}
[udpSocket enableBroadcast:YES error:&enableError];
if (enableError) {
NSLog(@"Error, can't enable broadcast: %@",[enableError localizedDescription]);
return;
}
if (![udpSocket beginReceiving:&receivingError])
{
NSLog(@"Error, can't receive: %@",[receivingError localizedDescription]);
return;
}
[self logInfo:@"Start listening to UDP boradcast channel"];
[self sendUdpSignal];
repeatedBroadcastTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(sendUdpSignal) userInfo:nil repeats:YES];
}
-(void)sendUdpSignal {
NSData* signal = [self udpBroadcastSignal] ;
NSLog(@"Send broadcast signal %@ on %@",signal, [self currentNetworkSsid]);
[udpSocket sendData:signal toHost:[self getBroadcastAddress] port:8089 withTimeout:10 tag:0];
}
你有什么建议吗? 有没有办法确保套接字接收永远不会停止?
提前致谢,
的Davide