1

私は非常に高速のUDPアプリケーションを使用しており、ここでの特定の基盤について少し興味があります。私はc#非同期メソッドを使用しており、EndReceiveで、作業を新しいスレッドに配置してから、BeginReceiveを呼び出しています。

現在EndReceiveとBeginReceiveの間のコードを使用している場合でも、WindowsはこのポートでUDPパケットを受け入れています。また、BeginReceiveを再度呼び出すと、次のパケットがスタックから取得されます。

これがすべて正しいと仮定すると(そうでない場合は、私をまっすぐに設定してください)-これらのパケットにTTLを指定することは可能ですか?送信者に応答を送信する必要があります。送信者は、数秒後に応答を無視するように構成されています。

ありがとう

4

3 に答える 3

4

ネットワーク インターフェイス カードがネットワークからデータグラムを配信すると、オペレーティング システムはそれをソケットの受信キューに入れます。recvfrom()システムコールまたは選択した高レベルラッパーでそれを読み取るまで、そこで待機します。

このバッファのサイズは、getsockopt()forを呼び出すことで確認できSO_RCVBUFます。デフォルト サイズと最大サイズは、オペレーティング システムとバージョンによって大きく異なります。

ネットワーク データグラムにはタイミング情報が含まれていないため、時間に基づいてそれらを期限切れにする本質的な方法はありません。どのように進めるかは、遅延がどこから来ると予想されるかによって異なります。

  • 送信から処理までの時間が気になる場合は、送信者と受信者の間でクロックを調整し、送信する直前に送信者に各データグラムにタイムスタンプを付けてもらう必要があります。これが、イベント間の実際の時間を知る唯一の方法です。ただし、ネットワークの遅延は大きく異なる可能性があるため、ある量よりも古いすべてのパケットを単純に破棄すると、すべてのパケットが破棄される可能性があることに注意してください

  • パケットが受信されてから処理されるまでの時間のみが問題である場合 (ネットワーク遅延は無視)、データグラムが到着するのと同じ速さで別のスレッドで読み取り、時間を記録して保存する必要があります。内部のスレッドセーフなキューで。これは多くの作業であり、かなりのオーバーヘッドが発生するため、最初に処理の遅延の原因を調べる必要がある場合があります。

  • パケットがかなり固定されたレートで送信されている場合、および/またはタイミングよりも未処理のパケットのバックログが問題である場合は、単純に受信キューのサイズを減らすことができます (setsockopt()を使用SO_RCVBUF)。受信キューがいっぱいになると、到着したデータグラムは黙って破棄されます。

于 2012-04-04T01:38:58.403 に答える
1

送信時にTTLを指定できますが、TTLは通過するときに各ルーターによってデクリメントされ、時間ベースではありません。これはあなたが探している分野ではありません。

したがって、パケットのTTLが3の場合、最初のルーターの後で2、2番目のルーターの後で1、3番目のルーターで0になり、送信者に通知されることなくパケットがドロップされます。

于 2012-05-04T14:40:02.267 に答える
1

パケットが古くなりすぎたときにパケットを破棄するという要件はアプリケーション固有であり、(AFAIK) UDP が提供できるものではありません。Windows は「自動的に」データグラムを受信して​​バッファリングしている可能性がありますが、それがどのように行われるかは、ネットワーク スタックの実装の詳細です。

これを 2 つの部分に分けます。

  1. メッセージが到着するとすぐに受信してキューに入れます。
    • 受信キューのサイズを制限したい場合は、この段階でも最も古いメッセージのドロップを開始する可能性があります。
  2. メッセージのデキュー:
    • 古すぎる場合は床に落とします。
    • それ以外の場合は、それらを処理および確認します。

ステップ 2 はおそらく並列化して、消費者が遅れないようにすることができます。

于 2012-04-02T16:04:48.270 に答える