GCDAsyncUdpSocket iOS上失踪多播数据包(GCDAsyncUdpSocket on

2019-07-03 10:51发布

我有一个多播通过UDP一个非常小的文件在网络上的设备。 在iOS应用我开发负责读取这些数据包,我选择了使用GCDAsyncUdpSocket这样做。 该文件被发送的每半秒,不过我没有收到它几乎经常(仅接受大约每3-10秒)。

认为它可能是设备的问题,我就开始监控与Wireshark的交通。 这似乎反映了我在我的应用程序中看到,直到我启用了“监控模式”在Wireshark的,在这一点每一个UDP数据包被捕获。 此外,iPhone模拟器开始接受所有丢失的数据包,因为它与分享我正在开发Mac上网卡。

有没有一种方法,使iOS设备或者我丢失的东西,将允许丢失的数据包进来的“监控模式”? 我也看到有在GCDAsyncUdpSocket一个readStream方法。 也许我需要改用beginReceiving的呢? 虽然我不知道如何设置在Objective-C流。如果是这样的话。

这里是我的测试代码,因为它是现在:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSLog(@"View Loaded");
    [self setupSocket];             
}

- (void)setupSocket
{
    udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    NSError *error = nil;
    if (![udpSocket bindToPort:5555 error:&error])
    {
        NSLog(@"Error binding to port: %@", error);
        return;
    }
    if(![udpSocket joinMulticastGroup:@"226.1.1.1" error:&error]){
        NSLog(@"Error connecting to multicast group: %@", error);
        return;
    }
    if (![udpSocket beginReceiving:&error])
    {
        NSLog(@"Error receiving: %@", error);
        return;
    }
    NSLog(@"Socket Ready");
}

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
      fromAddress:(NSData *)address
withFilterContext:(id)filterContext
{
    NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    if (msg)
    {
        NSLog(@"RCV: %@", msg);
    }
    else
    {
        NSString *host = nil;
        uint16_t port = 0;
        [GCDAsyncUdpSocket getHost:&host port:&port fromAddress:address];
        NSLog(@"Unknown message from : %@:%hu", host, port);
    }
}

解决方案任何人谁进来以后看这里:

基于ilmiacs的回答,我能够通过ping目标iOS设备,以减少显著丢失数据包的数量。 使用的是Mac,我在终端运行这一点 -

sudo ping -i 0.2 -s 4 <Target IP>

现在,我把它与Mac查验iOS设备上运行,我会寻找到苹果的iOS平的例子,看看我能有设备本身的ping来刺激自己的无线适配器(127.0.0.1)。

Answer 1:

通过我对网络的iOS设备我都发现,他们的网络适配器有两种不同模式的应用程序的工作,让我们称他们主动和被动。 我没能找到这个的任何文档。 这里是我的发现:

  1. 只要在主动模式下,适配器是非常敏感。 我有3-5ms的响应时间。

  2. 后闲置一段时间后,iOS版的网络适配器落在从主动到被动模式。 要做到这一点的时间,取决于实际的设备型号。 第三代iPad是200毫秒左右。 对于iPhone 4它更像是50毫秒。

  3. ping请求或TCP数据包将适配器从被动转移到活动模式。 这可能需要从东西向50毫秒800毫秒,平均约为200毫秒。

此行为是通过发出Ping命令完全可重复的。 例如

ping -i 0.2 <ios-device-ip>

设置ping时间间隔200毫秒,并保持我的iPad网络适配器处于活动状态。

此行为是与你的意见完全一致,如果(往往不是)适配器忽略UDP数据包在被动模式下。 Wireshark的活动可能保持它在主动模式,那么它会得到UDP图。

退房平技巧是否有所帮助。

一个也许可以通过打开和设备本身上连接两个插座,并定期将自身发送的数据包保持在活跃状态的iDevice的网络适配器。 这将介绍一些最小的开销。

至于苹果为何决定来实现这样的功能,我只能推测。 但可能保持适配器生效成本电量充足合法这样的设计选择。

希望这可以帮助。



Answer 2:

我遇到过同样的问题。

启动网络活动指示灯解决了这个问题对我来说:

UIApplication* app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = YES;


Answer 3:

如果你想查看iOS设备上的数据包,您可以系绳您的iOS设备到Mac,并使用安装WiFi适配器shell命令rvictl 。 然后,您可以使用Wireshark,tcpdump的,等来监控您的iOS设备上的802.11接口的流量。

至于不接收数据,直到3〜7秒 - 最有可能的设备已进入节电模式(IEEE PSM),它是802.11特征基本上使所述无线NIC睡觉。
PSM模式可以在设备产量表现不佳 -尤其是在你的情况,你有数据的周期性脉冲每1/2秒。 您的周期性平被唤醒网卡了。



文章来源: GCDAsyncUdpSocket on iOS missing multicasted datagrams