1

皆さん、こんにちは!
私はJava UDPサーバーを開発しています。サーバーに大量のデータを送信すると、受信バッファ サイズが小さいために受信パケットの一部が失われます。今、私はそのような方法で受信バッファを設定しています -

DatagramChannel serverChannel;
serverChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024*1024*10); // 10 MB


それは理にかなっていますか?このコードは、パケット損失の問題を解決しませんでした。私のオペレーティング システム - 64 ビット Windows 7.

もう 1 つ質問があります。私のネットワーク コントローラの受信バッファ プロパティはデフォルトで 512 です。これはバイト単位ですか、それともメガバイト単位ですか。512バイトの場合、このプロパティを手動で増やす必要がありますか? プログラムでバッファを増やすと、実際にはオペレーティングシステムのバッファが増えると思いますが、最初はudpパケットがネットワークカードに「来る」ため、これは意味がありません。

4

3 に答える 3

3

サーバーに大量のデータを送信すると、受信バッファ サイズが小さいために受信パケットの一部が失われます。

あなたはそれを知りません。多くの原因が考えられます。

今、私はそのような方法で受信バッファを設定しています -

DatagramChannel serverChannel;
serverChannel.setOption(StandardSocketOptions.SO_RCVBUF, 1024*1024*10); // 10 MB

それは理にかなっていますか?

実際には、これは膨大なバッファーであり、オペレーティング システムはそれをより適切なサイズに切り詰める場合があります。設定後にオプションを取得してみて、実際のサイズを確認してください。

このコードは、パケット損失の問題を解決しませんでした。

誰もそうするとは言わなかった。あなたはそれを仮定しただけです。

もう 1 つ質問があります。私のネットワーク コントローラの受信バッファ プロパティはデフォルトで 512 です。これはバイト単位ですか、それともメガバイト単位ですか。

使用している NIC を教えていただくまで誰も答えられませんが、製造元のデータからご自身で確認できるはずです。

512 バイトの場合、このプロパティを手動で増やす必要がありますか?

不必要なだけでなく、不可能です。

プログラムでバッファーを増やすと、実際にはオペレーティングシステムのバッファーが増加すると思います

ソケットの受信バッファ サイズを制御するという意味であればSO_RCVBUF、それは正しいです。

しかし、これは意味がありません

はい、そうです。

最初にudpパケットがネットワークカードに「来る」ためです。

そしてそこからオペレーティング システムへ、そこから IP スタックへ、そしてそこから UDP スタックへ、そしてそこからソケット受信バッファへ。ほとんどのパス MTU が最大 1500 バイトである場合、NIC が 512 バイトのバッファーを持つ可能性は低いようですが、たとえば 512k であることは理にかなっています。結局のところ、それで十分だと考えることができます。

あなたの基本的な仮定には欠陥があります。UDP パケットは、さまざまな理由で失われる可能性があります。送信されなかった、中間ルーターによってドロップされた、フラグメント化され、一部のフラグメントがレシーバーに届かなかった、またはレシーバーのソケット受信バッファーがいっぱいになったために、小さすぎるか、受信者が送信者に追いつけないことが原因である可能性があります。巨大なソケット レシーバー バッファーを使用するだけでは、これらの問題の 1 つにしか対処できません。信頼性が必要な場合は、TCP を使用するか、再試行を伴う ACK または NACK メカニズムを実装してください。

于 2013-03-18T03:48:12.623 に答える
1

それは意味がありますか?

すこし。ただし、UDPパケットが失われないことを保証することはできません。UDPは本質的に信頼性の低いプロトコルです。アプリケーションが追いつくのに十分な速さでパケットをソケットから引き出すことができない場合、またはネットワークエラーが発生した場合、パケットは失われます。

サーバーにデータを確実に送信する必要がある場合は、おそらくTCPを使用する必要があります...

私のネットワークコントローラーの受信バッファープロパティはデフォルトで512です-それはバイトですか、それともメガバイトですか?

わかりませんが、どちらも疑っています。キロバイトになる可能性が高くなります。


コントローラのバッファサイズを増やしてみました-OSは512が最大可能であると言っています)

それでは、10Mbに増やすことはできません。

したがって、newtworkエラーがない場合、処理が遅すぎる場合にのみパケットが失われます。

ではない正確に。パケットは、さまざまな原因で多くの場所で紛失/ドロップされる可能性があります。これらのいくつかは、「ネットワークエラー」ではなく「通常の動作」です。たとえば、ルーター/ブリッジ/ゲートウェイが混雑したときにパケットがドロップします。

バッファサイズを増やすことは問題を解決するのに十分に見えますが、驚くべきことに失敗します。

実際、それは驚くべきことではありません。パケットの損失は通常の動作である可能性があります。上記を参照。

「ワンスレッド」サーバーの開発に専念しているJavaNIOを使用している場合でも、あるスレッドでパケットを受信し、別のスレッドで処理する必要があるかもしれません。

OSおよびネットワークインターフェイスでのパケット損失を減らすのに役立つ場合があります。ただし、最終的にはアプリケーションメモリにデータをバッファリングすることになり、アプリケーションが長期的に追いつかない場合は、さらに悪い問題が発生する可能性があります。

また、他の理由で紛失/ドロップされたパケットは処理しません。


肝心なのは、UDPを使用して信頼性の高いロスレス伝送を実現することはできないということです。パケット損失は避けられず、それを回避しようとして時間を無駄にしています。

失われたデータグラムに対処するようにアプリケーションを設計するか、TCPまたは信頼性の高いデータ転送を提供するその他のプロトコルの使用に切り替える必要があります。

于 2013-03-18T03:42:20.100 に答える
1

UDP は個別のパケットを送受信します。最大サイズは約 65K です。これより多くのデータを送信する場合は、複数のパケットに分割する必要があります。また、他の人が指摘しているように、UDP は信頼できないプロトコルです。パケットが消えたり、重複したり、順不同で受信される場合があります。

于 2013-03-18T03:48:31.683 に答える