5

私は、UDP を使用してファイルを転送するという古典的なタスクを与えられました。さまざまなリソースで、パケットのエラーのチェック (パケットにデータと一緒に CRC を追加する) が必要であり、UDP は既に破損したパケットをチェックして破棄しているため、ドロップされたパケットの再送信についてのみ心配する必要があることを読みました。

どちらが正しいですか?到着したパケットの整合性チェックを手動で実行する必要がありますか? または、正しくないパケットは既に破棄されていますか?

ちなみにプロジェクトの言語はJavaです。

編集: 一部の情報源 (コースブック、インターネット) は、チェックサムがヘッダーのみをカバーしているため、送信者と受信者の IP が正しいことを保証するなどと言っいます。一部の情報源によると、チェックサムデータセグメントをカバーする可能性がありますが、それはオプションであり、OS によって決定されます。

編集 2: 教授に尋ねたところ、データ セグメントの UDP エラー チェックは IPv4 ではオプションであり、IPv6 ではデフォルトであるとのことです。しかし、それがプログラマーの制御下にあるのか、OSの制御下にあるのか、それとも別のレイヤーにあるのかはまだわかりません...

4

4 に答える 4

4

最初の事実:

UDP には、パケット ヘッダーのビット 40 から始まる 16 ビットのチェックサム フィールドがあります。これには、(少なくとも) 2 つの弱点があります。

  • チェックサムは必須ではありません。0 に設定されたすべてのビットは「チェックサムなし」として定義されます。
  • これは厳密な意味で16 ビットのチェックサムであるため、検出されない破損の影響を受けやすくなっています。

つまり、環境によっては、UDP の組み込みチェックサムが十分に信頼できる場合とそうでない場合があります。

第二の事実:

トランスポートに沿ったデータ破損よりもさらに現実的な脅威は、パケット損失の並べ替えです。USP は次のことについて保証しません。

  • (最終的に)到着するすべてのパケット
  • パケットが送信されたのと同じ順序で到着する

実際、UDP には、単一のパケットよりも大きなペイロードを処理するための組み込みメカニズムがまったくありません。これは、そのために構築されていないという事実に起因します。

結論:

追加の手段なしで受信したパケットを次々と追加すると、非常に好ましい環境を除くすべての環境で送信ストリームとは異なる受信ストリームが生成され、直接ファイル転送に最適なプロトコルとは言えません。

UDP を使用してファイルを転送したい、または使用しなければならない場合は、TCP には不可欠であるが UDP には不可欠ではない部分をアプリケーションに組み込む必要があります。ただし、これにより、TCP の再実装が不十分になる可能性が高いということわざがあります。

成功した実装には、多くのピア ツー ピア ファイル共有プロトコルが含まれます。これらのプロトコルでは、接続の中断やパケットの損失に対する保護、またはフィルタを無効にするか軽減するために、アプリケーションの機能の一部として並べ替えを行う必要があります。

実装の推奨事項:

私たちにとってうまくいったのは、チャンク ウィンドウの実装です。ペイロードは固定された便利な長さのチャンクに分割され (1023 バイトを使用しました)、N 個のチャンクのステータス配列が送信側と受信側で保持されます。

送信側:

  • そのようなチャンク、ストリーム内のそのシーケンス番号 (複数回)、およびチェックサムまたはハッシュを含む UDP メッセージが開始されます。
  • ステータス配列は、タイムスタンプでこのチャンクを「送信済み/保留中」としてマークします
  • 完全なステータス配列 (送信ウィンドウ) が消費されると、送信が停止します

受信側:

  • 受信したパケットはチェックサムに対してチェックされます。
  • 破損したパケットは、シーケンス番号のすべてのコピーが一致する場合は否定的に確認され、そうでない場合はドロップされます
  • OK パケットはステータス配列で「受信済み/保留中」としてタイムスタンプ付きでマークされます
  • ACK パケットを満たすのに十分なチャンクが受信された場合、または最も古い「受信/保留中」のタイムスタンプが古すぎる (数ミリ秒から数 100 ミリ秒) 場合、確認応答は ack パケットを送信することによって機能します。
  • Ack パケットにはチェックサムが必要ですが、順序付けは必要ありません。
  • 確認応答が送信されたチャンクは、ステータス配列にタイムスタンプを付けて「確認/保留中」としてマークされます

送信側:

  • Ack パケットを受信して​​チェックし、破損したパケットをドロップします
  • ack が受信されたチャンクは、ステータス配列で「ack/done」としてマークされます
  • ステータス配列の最初のチャンクが「ack/done」とマークされている場合、ステータス配列は、最初のチャンクが再び完了しないまでスライドアップします。
  • これにより、送信される 1 つ以上の未送信チャンクが解放される可能性があります。
  • ステータスが「送信済み/保留中」のチャンクの場合、元のチャンクが失われた可能性があるため、タイムスタンプのタイムアウトにより、このチャンクの新しい送信がトリガーされます。

受信側:

  • チャンク i+N (N はウィンドウ幅) を受信すると、チャンク i に ack/done のマークが付けられ、受信ウィンドウが上にスライドします。受信ウィンドウからスライドするすべてのチャンクが「ack/pending」としてマークされていない場合、これは回復不能なエラーを構成します。
  • ステータスが「ack/pending」のチャンクの場合、元の ack メッセージが失われた可能性があるため、タイムスタンプのタイムアウトにより、このチャンクの新しい ack がトリガーされます。

明らかに、送信ウィンドウがファイルの最後をスライドする場合、チャンク N+i を送信せずに ack の受信を通知するために、送信側から特別なメッセージ タイプが必要です。存在しますが、ペイロードはありません。

于 2013-04-02T18:13:32.323 に答える
2

受信したパケットが送信されたものと同じであることを確認できます (つまり、パケット A を送信し、パケット A を受信した場合、それらが同一であることを確認できます)。パケットのトランスポート層 CRC チェックにより、これが保証されます。ただし、UDP には配送の保証がないため、送信されたものをすべて受け取ったことを確認し、正しく注文したことを確認する必要があります。

つまり、パケット A、B、および C がこの順序で送信された場合、実際には A と B のみを受信する (またはまったく受信しない) 可能性があります。C、B、A のように順不同になる可能性があります。したがって、チェックでは、TCP が提供する配信保証の側面を処理する必要があります (順序を確認し、すべてのデータがそこにあることを確認し、送信しなかったものを再送信するようにサーバーに通知します)。 t 受信)必要な程度に

TCP よりも UDP を優先する理由は、一部のアプリケーションでは、データの順序もデータの完全性も問題にならないためです。たとえば、AAC オーディオ パケットをストリーミングする場合、個々のオーディオ フレームは非常に小さいため、リスニング エクスペリエンスを著しく損なうことなく、少量のフレームを安全に破棄したり、順不同で再生したりできます。パケットの 99.9% が受信され、正しく順序付けされている場合、ストリームを問題なく再生でき、誰も気付かないでしょう。これは、一部のセルラー/モバイル アプリケーションではうまく機能し、欠落したフレームの再送信について心配する必要さえありません (Shoutcast やその他の一部のサーバーは、[帯域内メタデータを容易にするために] ストリーミングに TCP を使用する場合があることに注意してください。する必要はありません)。

すべてのデータがそこにあり、正しく順序付けされていることを確認する必要がある場合は、TCP を使用する必要があります。TCP は、データがすべてそこにあることを確認し、正しく順序付けし、必要に応じて再送信します。

于 2013-04-02T17:45:31.940 に答える
2

UDP プロトコルは、エラーのあるパケットをチェックするために、TCP プロトコルが使用するのと同じ戦略 (パケット ヘッダーの 16 ビット チェックサム) を使用します。

UDP パケット構造は (TCP と同様に) よく知られているため、暗号化されていない場合、パケットは簡単に改ざんできます。別のチェックサム (CRC-32 など) を追加すると、より堅牢になります。目的がデータの暗号化 (手動または SSL チャネル経由) である場合、別のチェックサムをわざわざ追加する必要はありません。

パケットが 2 回送信される可能性があることも考慮してください。それに応じて対処するようにしてください。

ウィキペディアで両方のパケット構造を確認できます。どちらにもチェックサムがあります。

TCP パケット構造をより詳細に確認して、ドロップされたパケットの処理方法に関するヒントを得ることができます。TCP プロトコルは、そのために「シーケンス番号」と「確認番号」を使用します。

これがお役に立てば幸いです。幸運を祈ります。

于 2013-04-02T18:21:24.990 に答える
1

UDP は、パケットごとの内部チェックサムを満たさないパケットをドロップします。CRC チェックは、ペイロードが完全に見えたら、受信したものが実際に完全であり (ドロップされたパケットがない)、送信されたものと一致する (中間者攻撃やその他の攻撃がない) かどうかをアプリケーション層で判断するのに役立ちます。 .

于 2013-04-02T17:34:39.920 に答える