2016-11-22 20 views
0

私のudp受信機ソケットはかなり標準的な設定です。私の送信者は36Hzでデータを送信し、受信者は72Hzでデータを送信します。送信あたり12072バイト。C++ udp recvfrom reduce drops

私はcat/proc/net/udpをいつ行うのですか?私は通常得る

sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops 
7017: 0101007F:0035 00000000:0000 07 00000000:00000000 00:00000000 00000000  0  0 10636 2 0000000000000000 0   
7032: 00000000:0044 00000000:0000 07 00000000:00000000 00:00000000 00000000  0  0 14671 2 0000000000000000 0   
7595: 00000000:0277 00000000:0000 07 00000000:00000000 00:00000000 00000000  0  0 11113 2 0000000000000000 0   
7660: 00000000:22B8 00000000:0000 07 00000000:00004100 00:00000000 00000000 1000  0 251331 3 0000000000000000 352743 

あなたはrx_queueがそこにいくつかの値を持っているのを見ることができますか?

私のコード

int recv_len = recvfrom(s, buf, BUFLEN, MSG_TRUNC, (struct sockaddr *) &si_other, &slen); 
    // dont worry buflen is like 64000 no error here 

    std::cout <<" recv_len "<<recv_len<<std::endl; 

私は常にキューが非常に大きい場合でも12072 recv_lenとして出力を得ますか?どうしてこれなの ?私の読書をスピードアップしたり、キュー内のすべてのメッセージを読む方法はありますか?私は読んでいる頻度がもっと高くても何が間違っているのか分かりません。

+0

あなたのコードは、それはやっている? (例えば、あなたは72HZで読んでいると思いますが、そうではありません。または、あなたがキャッチしたことのない単純なバグがあります) – nos

答えて

0

UDPデータグラムは、常に完全なアトミック単位として移動します。 12072 UDPデータグラムを送信すると、受信者は正確に1つの12072データグラムを取得するか、まったく取得しません。部分的なメッセージ(*)または連結された複数のメッセージは受信されません。

このサイズのデータ​​グラムでは、おそらくネットワークのMTU(最大送信単位)よりも大きいため、IP層でフラグメント化されている可能性があります。その場合、フラグメントのいずれか1つが途中または受信側ホストにドロップされた場合、または破損していると判明した場合、UDPデータグラム全体が破棄されます。

recvfromに提供するバッファが小さすぎですが、メッセージ全体がカーネルで再構築することができなかった場合はそれも受信するために考慮されることはありません場合*メッセージ切り捨てられることがあります。)

の場合送信されているすべてのメッセージを受け取ることができない場合は、UDPに割り当てられたカーネルバッファスペースを増やす必要があるかどうかを確認します。これはsysctlユーティリティで行われます。具体的には、net.core.rmem_maxnet.ipv4.udp_memの値を確認し、調整する必要があります。対応するドキュメントを参照してください:
最後に https://www.kernel.org/doc/Documentation/sysctl/net.txt
https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

を、それが「周波数を読む」について話を少し好奇心が強いようだ - 私はそれはあなたがソケットをポーリングしている毎秒72回の意味と仮定しますか?なぜソケットを読み込み専用にするのではないのでしょうか。スレッドはrecvfromでブロックすることができ、最小限のレイテンシで受信が完了します。 (いずれにしても、テストの場合でも、ポーリングがあなたの送信者に追いつくことができないかどうかを確認するには、これは試してみる価値があります)。

+0

カーネルレベルで何か起こっていると思います。 1スレッドを捧げることで、大幅にはなりませんが、ドロップ数は減少します。しかしもっと重要なことは、送信者からメッセージを処理するポイントまでの遅延を減らすことです。私はudp_memのサイズを調べ、それらの値で遊びます。 – itsnevertoobadtoaskforhelp

関連する問題