2012-10-28 14 views
6

ネットワーク上にUDP経由で非常に小さなファイルをマルチキャストするデバイスがあります。私が開発しているiOSアプリはこれらのパケットを読む責任があり、私はGCDAsyncUdpSocketを使用することにしました。ファイルは0.5秒ごとに送信されますが、私はそれほど頻繁に受信しません(約3-10秒ごとに受信します)。iOSのGCDAsyncUdpSocketにマルチキャストされたデータグラムがありません

デバイスに問題があると考えて、私はWiresharkでトラフィックを監視し始めました。これはWiresharkの "Monitor Mode"を有効にするまで、私のアプリで見ていたものを反映しているように見えました。その時点で、すべての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を実行することで、欠落しているパケットの数を大幅に減らすことができます。今、私はそれは、私はAppleのiOSのpingを例に見て、私は、デバイスを持つことができるかどうかを確認するつもりですMacがiOSデバイスにpingを送信して実行していることを

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

- のMacを使用して、私はターミナルでこれを実行しました独自の無線アダプタ(127.0.0.1)を刺激するためにpingを行います。

+0

あなたは、UDPパケットが**デザインによって提供されていない**ことを認識していますか?アプリケーションでこのケースを処理できる必要があります。 –

+0

はい、私はUDPが信頼できないことを知っていますが、本当に多くのパケットがキャプチャされていない原因になるのでしょうか?また、NICがモニタモードを有効にしている限り、アプリは問題なくすべてのパケットを受信します。 – Squatch

+0

@Squatchどのデバイスを使用したのかわかりますか? –

答えて

12

iOSデバイス用のネットワーキングアプリケーションに関する私の作業を通じて、ネットワークアダプタには2つの異なるモードがあることが明らかになりました。私はこれに関する文書を見つけることはできませんでした。ここに私の所見があります:

  1. アクティブモードでは、アダプタは非常に応答性があります。私は3-5msの応答時間があります。

  2. iOSのネットワークアダプタは、しばらくしてからアクティブモードからパッシブモードに切り替わります。これが起こる時間は、実際のデバイスモデルによって異なります。 3rd gen iPadは約200msです。 iPhone 4の場合は、50msほどです。

  3. ping要求またはTCPパケットは、パッシブモードからアクティブモードにアダプタを移動します。これには、50ms〜800msの間で、平均で約200msかかるものがあります。

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

ping -i 0.2 <ios-device-ip> 

は、ping間隔を200msに設定し、iPadsネットワークアダプタをアクティブ状態に保ちます。

この動作は、パッシブモードのときにアダプタ(多くの場合より多くの場合)がUDPパケットを無視すると、観察と完全に一致します。 wiresharkの活動はおそらくそれをアクティブモードに保ちますので、UDPを取得します。

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

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

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

これが役に立ちます。

+0

とても面白いです。私はそれを試みることは決して考えなかったでしょう。私は今夜​​これを試してみる。 – Squatch

+0

はい、私たちは少なくとも1ヶ月のレイテンシの振る舞いについて困惑していました。 ;-) – ilmiacs

+0

それは働いた!私はまだいくつかのパケットが欠落していますが、無視できる量です。本当にありがとう。 – Squatch

1

私は同じ問題がありました。ネットワークアクティビティインジケータを開始

は私のためにその問題を解決:

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

あなたはiOSデバイス上のパケットを表示したい場合は、あなたがMacにiOSデバイスをつなぐとshell command rvictlを使用して無線LANアダプタを装着することができます。 wireshark、tcpdumpなどを使用して、iOSデバイス上の802.11インターフェイスのトラフィックを監視することができます。

3〜7秒までデータを受信しない限り、お使いのデバイスは基本的にワイヤレスNICをスリープ状態にする802.11機能である省電力モード(IEEE PSM)に入っている可能性があります。
PSMモードcan yield poor performance on devices - 特に、1/2秒ごとに周期的なデータバーストが発生する場合は、定期的なpingがNICを起動しています。