2011-10-10 10 views
0

マシンAとマシンBで、両方ともUbuntu Server 11.04がインストールされた状態で実験を行っています。 AとBは同じ1000M/bpsスイッチに接続されています。受信機なぜこのJavaプログラムはUDPパケットの損失を引き起こしますか?

一方(総< = 10,000) send_udp_datagramPacket(新しいバイトが[100])

BをBである:(真) 受信

一方

Aが送信元であります()

しかし、ついに私は10,000点(約9960点)を得ました。これはどうして起こったのですか? 紛失したパケットはどこに行きましたか?実際にスイッチにワイヤに送られなかったのでしょうか?またはスイッチがそれらを失った?あるいは彼らは本当にBに行きましたが、BのOSはそれらを捨てましたか?それともJavaに到達したのですが、Javaは完全なバッファーのためにそれらを投げ捨てましたか?

ご回答いただければ幸いです。

+6

UDPは接続がなく、保証されません。 UDPパケットを送信すると、*それが受信されるという保証はありません。ローカルネットワークにパケットを流して、いくらか失うことになります。 –

+2

Wiresharkの使用を強くお勧めします。これは、これらの質問のいくつか(例えば、何が電線上にあったかなど)に答えるのに役立ちます。また、ハードウェア全体で異なるUDP負荷をテストするには、単純な「UDP ping」で十分です。 –

+0

upvoted無意味なdownvoteアップ。 – EJP

答えて

5

UDPは信頼性の高い通信を提供しないことを覚えておいてください。データ損失が許容される状況(例:ストリーミングメディア)に適しています。これはバッファオーバーフロー(私の推測では、それに頼ってはいけない)である可能性がありますが、このデータ損失が許容できない場合は、代わりにTCPを使用することが重要です。

これは実験のためだけであれば、ループ内で遅延(Thread.sleep())を追加してみてください、あなたは最大受信したパケットを取得するまでそれを上げます。

EDIT: コメントに記載されているように、sleep()は修正ではなく、最終的にはパケットを失うでしょう。それはUDPだけです。

+0

しかし、最終コードにsleep()を残さないでください。それは壊れるでしょう。 –

2

最後に、私はBで10,000(約9960)未満でした。なぜこれが起こっていますか?

UDPは非可逆プロトコルです。このテストで10,000を得たとしても、パケットが失われる可能性をコードする必要があります。それらは断片化されてもよく(532バイトより大きい場合)、および/または順序が乱れて到着してもよい。

失われたパッケージには行きましたか?

これを削除しました。

彼らは実際には、スイッチに電線に送信されませんでしたか?

彼らはちょうど約どこでもドロップすることができます。私はJavaにパケットをドロップするロジックがないと信じています(ただし、これはすべての実装で保証されているわけではありません)。OSによって壊される可能性があり、ネットワークアダプタがワイヤで破損し、

またはスイッチにそれらを失いましたか?

パケットが何らかの方法で破損したか、バッファがいっぱいになった場合にこれが実行されます。

実際にはBにはなっていますが、BのOSはそれらを破棄しましたか?

はい、またはAのOSがそれらを破棄している可能性があります。

またはJavaに到達しましたが、JavaはフルバッファーのためにJavaを破棄しましたか?

Javaには独自のバッファがありません。これは、OSの基本バッファを使用します。しかし、パケットはこの段階で失われる可能性があります。

注:パケット損失をどれだけ減らしても、常に損失を許容する必要があります。

+1

「Javaにパケットをドロップするロジックがないとは思わない」:間違いなく。それらを送受信するロジックを持っています。基礎となるIPスタックがしないことは何もしません。 – EJP

1

なぜこのJavaプログラムによってUDPパケットが失われるのですか?

質問が不適切です。 JavaもプログラムもUDPパケットの損失を引き起こしません。 UDPはUDPパケット損失を引き起こします。 UDPパケットが到着する保証はありません。 RFC 768を参照してください。

関連する問題