7

ネットワーク上に、UDPを介して非常に小さなファイルをマルチキャストしているデバイスがあります。私が開発しているiOSアプリは、これらのパケットの読み取りを担当しており、GCDAsyncUdpSocketを使用して読み取ることを選択しました。ファイルは0.5秒ごとに送信されますが、私はそれほど頻繁には受信していません(約3〜10秒ごとにのみ受信しています)。

デバイスに問題があるのではないかと考え、Wiresharkでトラフィックの監視を開始しました。これは、Wiresharkで「監視モード」を有効にするまでアプリに表示されていたものを反映しているように見えました。有効にすると、すべてのUDPパケットがキャプチャされていました。さらに、iOSシミュレーターは、私が開発しているMacとNICを共有しているため、欠落しているすべてのパケットの受信を開始しました。

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の回答に基づいて、ターゲットのiOSデバイスにpingを実行することで、欠落しているパケットの数を大幅に減らすことができました。Macを使用して、これをターミナルで実行しました-

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

MacでiOSデバイスにpingを実行して実行しているので、AppleのiOS pingの例を調べて、デバイス自体にpingを実行して独自のワイヤレスアダプター(127.0.0.1)を刺激できるかどうかを確認します。

4

3 に答える 3

13

iOS デバイス用のネットワーク アプリに関する私の作業を通じて、それらのネットワーク アダプターには 2 つの異なるモードがあることを明らかにしました。それらをアクティブ モードとパッシブ モードと呼びましょう。これに関するドキュメントを見つけることができませんでした。ここに私の発見があります:

  1. アクティブ モードである限り、アダプターは非常に応答性が高くなります。応答時間は 3 ~ 5 ミリ秒です。

  2. しばらく非アクティブ状態が続くと、iOS のネットワーク アダプタがアクティブ モードからパッシブ モードに移行します。これが発生する時間は、実際のデバイス モデルによって異なります。第 3 世代 iPad では約 200ms です。iPhone 4 の場合は 50ms に近いです。

  3. ping 要求または TCP パケットは、アダプターをパッシブ モードからアクティブ モードに移行します。これには 50 ミリ秒から 800 ミリ秒かかる場合があり、平均は約 200 ミリ秒です。

この動作は、ping コマンドを発行することで完全に再現できます。例えば

ping -i 0.2 <ios-device-ip>

ping 間隔を 200 ミリ秒に設定し、iPad のネットワーク アダプタをアクティブな状態に保ちます。

この動作は、パッシブ モードのときにアダプターが (ほとんどの場合) UDP パケットを無視する場合、観察結果と完全に一致しています。Wireshark アクティビティにより、おそらくアクティブ モードが維持されるため、UDP が取得されます。

ping トリックが役立つかどうかを確認してください。

おそらく、デバイス自体で 2 つのソケットを開いて接続し、定期的にパケットを送信することで、iDevice のネットワーク アダプタをアクティブな状態に保つことができます。これにより、最小限のオーバーヘッドが発生します。

Apple がそのような機能を実装することにした理由については、推測するしかありません。しかし、おそらくアダプターをアクティブにしておくと、そのような設計の選択を正当化するのに十分なバッテリー電力が必要になります。

お役に立てれば。

于 2013-01-17T15:27:03.450 に答える