TCP / UDPとイーサネットのMTU断片化
-
18-09-2019 - |
質問
私は、オンラインで様々なサイトとチュートリアルを読んだが、私はまだ混乱しています。メッセージは、IP MTUよりも大きい場合には、send()
が送信されたバイトを返します。何がメッセージの残りの部分になりますか?私は再びsend()
を呼び出し、メッセージの残りの部分を送信しようとするのですか?それとも何かIP層は自動的にの世話をするべきであるということです?
解決
あなたはTCPを使用している場合は、あなたに提示インタフェースは、バイトストリームのものです。あなたはバイトのストリームは他への接続の一端から取得する方法について心配する必要はありません。あなたは、IPレイヤのMTUを無視することができます。実際には、あなたは完全にIPレイヤを無視することができます。
あなたがあなたの送信に推進しているバイトのストリームのために必要なすべての詳細を扱いますあなたのマシン上でsend()
TCPスタックを呼び出すと、 recv()
は、接続のもう一方の端に呼び出してから表示されるように呼び出します。
覚えておくべき一つのことは、TCPを使用すると、ストリームを扱っているし、それが1 send()
が単一recv()
コールに到着したデータをもたらすことができる複数のsend()
コールや複数recv()
コールに到着したデータをもたらすことができることを意味していることです。あなたはこのを制御することはできません。あなたはバイトのストリームを扱っているとrecv()
への各呼び出しは、1から(recv()
コールに渡さ十分なバッファを可能にする)現在のアウトスタンディング数に任意のバイト数を返すことができます。
コメンターはそれを求めているので;)
ほとんどのTCP上でTCPスタックのバッファがいっぱいであると、(おそらく)TCPウィンドウもいっぱいで、フロー制御をするのでsend()
がすべてを送信するために失敗する可能性が最も高いスタックは、スタックは、それ以上を送信できないことを意味して運転されていますデータいくつかのデータのACKリモート終了時まで、それはあなたに代わって、それ以上バッファリングする準備ができていないのです。私はのみによるMTUの考慮にsend()
を拒否しますTCPスタックに遭遇していませんでしたが、私はそのように振る舞うかもしれないいくつかのスリム化の組み込みシステムを推測...
とにかく、send()
は、あなたがそれはあなたがいくつかの点で、残りのデータを再送信する必要があります与えたバイト数よりも少ない返した場合。多くの場合、ブロックと、それはすべてのデータを送信できるようになるまで待機しますsend()
、あなたが非ブロッキングモードにソケットを設定している場合、それはあなたがおそらく終わるだろう、すべてを送信するために失敗した場合、あなたはおそらくすぐに送信を再試行する必要はありませんタイトなループ内でアップ...
これはおそらく有用であろう。
他のヒント
ネットワークICMPの断片化のヒントは、パケットサイズを小さくして再試行して送信者に信号を送る送信されます。
あなたはTCPを使用する場合、これらはすべての詳細であるあなたはあなたのための世話をするために、ネットワーク層を期待するべきです。どのような近代的なIPは実際のパスに沿って、最も低いMTUを把握するために舞台裏でやっていることは、やや黒魔術のようになったようだスタックます。
WRT UDPは、あなたはまだ、スタックがあなたのために断片化を期待することができますが、実用的にUDPのためのユースケース与えられたその理想的ではありません...あなたのアプリケーションに応じて、明示的にパスMTUを理解することによって、より良いパフォーマンスを参照してくださいする可能性があります。
...センドの()質問いくつかのスタックは異なる動作をしかし、治療WRTあなたのコードが同じである必要があります。送信された10のバイトを返す()送信...あなたが送信するために100のバイトを考えてみましょう。あなたはそのすべてが全体のメッセージを送信するために、ワイヤを押し出されるまで、残りの90バイトで送信呼び出しておく必要があります。
すべてはあなたがデータをプッシュするために、より頻繁に送信しておく必要があります。他のプラットフォームでは...のLinuxら送信された後、)(Windowsプラットフォームの送信時に、ブロッキングソケットを使用してUsusallyに戻ります。