iOs上的UDP包丢失很高(GCDAsyncUdpSockets)

时间:2014-09-21 16:03:52

标签: ios iphone sockets udp cocoaasyncsocket

我正在开发一款用于控制物理硬件的iPhone应用程序 例程如下:

  • app发送一个特定的8字节"唤醒"广播信道上的数据报,在端口8089上;邮件重复发送。
  • 正在侦听端口8089的外部硬件接收消息并发送一个94字节的数据报,其中包含硬件的IP和MAC地址;这也是在广播频道上。
  • app停止发送"唤醒"消息,存储IP,并开始通过TCP套接字与硬件通信

该例程通常有效。但是,我常常在接收时遇到无法解释的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

0 个答案:

没有答案