3

オンラインでさまざまなサイトやチュートリアルを読みましたが、まだ混乱しています。メッセージが IP MTU より大きい場合は、send()送信されたバイトを返します。メッセージの残りの部分はどうなりますか? もう一度電話send()して、残りのメッセージを送信する必要がありますか? それとも、IP レイヤーが自動的に処理する必要があるものですか?

4

2 に答える 2

6

TCP を使用している場合、表示されるインターフェイスはバイト ストリームのインターフェイスです。バイト ストリームが接続の一方の端から他方の端までどのように取得されるかについて心配する必要はありません。IP 層の MTU は無視できます。実際、IP 層は完全に無視できます。

マシンの TCP スタックを呼び出すとsend()、送信呼び出しにプッシュしているバイト ストリームがrecv()接続の反対側の呼び出しから表示されるために必要なすべての詳細が処理されます。

覚えておくべきことの 1 つは、TCP ではストリームを扱っているということです。つまり、1 つの呼び出しで複数の呼び出しでデータが到着する可能性があり、複数の呼び出しで 1 つの呼び出しsend()でデータが到着する可能性があることを意味します。これを制御することはできません。バイトのストリームを扱っており、各呼び出しは 1 から現在未処理の数までの任意のバイト数を返すことができます (呼び出しに渡される十分なバッファーを許可します)。recv()send()recv()recv()recv()

コメンターがそれを求めたので;)

ほとんどの TCP スタックsend()では、TCP スタックのバッファがいっぱいで、(おそらく) TCP ウィンドウもいっぱいで、フロー制御が動作しているため、すべての送信に失敗する可能性が最も高くなります。 end 一部のデータに ACK を送信し、ユーザーに代わってこれ以上バッファリングする準備ができていません。send()MTU の考慮事項だけで拒否する TCP スタックに出くわしたことはありませんが、一部のスリム化された組み込みシステムはそのように動作する可能性があると思います...

いずれにせよ、send()返されたバイト数が指定したバイト数よりも少ない場合は、残りのデータをある時点で再送信する必要があります。多くsend()の場合、すべてのデータを送信できるようになるまでブロックして待機します。ソケットを非ブロック モードに設定している場合は、すべての送信に失敗した場合にすぐに送信を再試行したくない可能性があります。タイトなループで...

使用しているオペレーティング システムについて、より具体的な情報を提供していただけると助かります。

于 2010-03-09T08:03:16.750 に答える
0

パケットが大きすぎてネットワークを通過できない場合は、ICMP フラグメンテーション ヒントが送信され、パケット サイズを小さくして再試行するよう送信者に通知します。

TCP を使用する場合、これらはすべて、ネットワーク層が処理することを期待する必要がある詳細です。パスに沿って最小の MTU を把握するために、最新の IP スタックが実際に舞台裏で行っていることは、やや黒魔術のようになっているようです。

WRT UDP では、スタックがフラグメント化されることを期待できますが、実際には UDP のユース ケースを考えると理想的ではありません。アプリケーションによっては、パス MTU を明示的に理解することでパフォーマンスが向上する可能性があります。

... send() の質問では、一部のスタックの動作が異なりますが、コードの WRT の扱いは同じである必要があります。送信する 100 バイトがあるとしましょう... send() は、送信された 10 バイトを返します。メッセージ全体を送信するためにすべてがワイヤから押し出されるまで、残りの 90 バイトで send を呼び出し続ける必要があります。

Windows プラットフォームでブロッキング ソケットを使用すると、send() は通常、すべてが送信された後に返されます.. 他のプラットフォームでは.. Linux などでは、データをプッシュするために、より頻繁に送信し続ける必要があります。

于 2010-03-09T08:18:53.173 に答える