web-dev-qa-db-ja.com

TCPネットワークパケットがアプリケーション層で断片化されるのはいつですか?

TCPパケットはアプリケーション層で断片化されますか?TCPパケットがアプリケーションから送信されると、アプリケーション層の受信者はパケットが2つ以上のパケットに含まれている場合、どのような条件でパケットが分割されますか?パケットは、イーサネット(ネットワーク層)の1500バイトの制限に到達するまで断片化されないようです。ネットワーク層はパケットを次の層に送信する前にフラグメントを再構築するため、アプリケーション層の受信者に対して透過的になりますか?

34
zooropa

MTUがパケットサイズよりも小さいネットワークデバイスにヒットすると、分割されます。ほとんどのイーサネットデバイスは1500ですが、ルーティング情報が余分にあるため、イーサネットがPPPoE(DSL)を超えている場合は1492より小さくなります。Windowsのように2番目のレイヤーが追加されるとさらに低くなりますインターネット接続の共有およびダイヤルアップは通常576です!

一般的には、TCPはパケットプロトコルではないであることを覚えておく必要があります。最下位レベルのパケットを使用してIPで送信しますが、TCPスタックのインターフェイスに関する限り、ストリームプロトコルであり、1を提供する必要はありません。 1送受信される物理パケットとの関係(たとえば、ほとんどのスタックは、一定期間が経過するまでメッセージを保持するか、特定のMTUのIPパケットのサイズを最大化するのに十分なメッセージがある)

例として、2つの「パケット」を送信した場合(送信機能を2回呼び出す)、受信プログラムは1つの「パケット」しか受信しない可能性があります(受信側TCPスタックはそれらを結合します)。 TCP上のメッセージタイププロトコルを実装している場合、各メッセージの先頭にヘッダー(または他のヘッダー/フッターメカニズム)を含めて、受信側がTCPストリームをメッセージが2つの部分で受信される場合、またはいくつかのメッセージがチャンクとして受信される場合の個々のメッセージ。

37
David

フラグメンテーションは、TCPアプリケーションに対して透過的である必要があります。TCPはストリームプロトコルであることに注意してください。パケットではなくデータのストリームを取得します!完全なデータパケットの概念に基づいてアプリケーションを構築すると、抽象化レイヤーを追加してストリームからパケット全体を組み立ててから、パケットをアプリケーションに渡さない限り、問題が発生します。

16
dwc

この質問は、正しくないという仮定を立てています-TCPは、エンドポイントにパケットを配信せず、バイト(オクテット)のストリームを送信します。アプリケーションがTCPに2つの文字列を書き込む場合、もう一方の端で1つの文字列として配信される場合もあります;同様に、もう一方の端で1つの文字列が2つ(またはそれ以上)の文字列として配信される場合もあります。

RFC 79 、セクション1.5:

「TCPは、インターネットシステムを介して送信するために、いくつかのオクテットをセグメントにパッケージ化することにより、各方向にオクテットの連続ストリームを転送できます。」

キーワードは、オクテットの連続ストリーム(バイト)です。

RFC 79 、セクション2.8:

「プッシュ関数とセグメント境界の間に必要な関係はありません。特定のセグメントのデータは、全体または一部の単一のSEND呼び出し、または複数のSEND呼び出しの結果である可能性があります。」

セクション2.8の全体が関連しています。

11
Kevin Panko

アプリケーション層では、1500バイト全体が1回の読み取りに表示されない理由がいくつかあります。内部オペレーティングシステムとTCPスタックのさまざまな要因により、アプリケーションは1回の読み取り呼び出しでいくつかのバイトを取得し、次の読み取り呼び出しでいくつかのバイトを取得する場合があります。はい、TCPスタックはパケットを送信する前に再組み立てする必要がありますが、それはアプリが一度にすべてを取得しようとしているという意味ではありません(1回の読み取りで取得する可能性が高いです) 、ただし、一度の読み取りで取得することは保証されていません)。

TCPは、エラーチェック、自動再送信などが背後で発生するなど、バイトの順序配信を保証しようとします。アプリ層でのパイプと考えて、スタックが実際にネットワークを介して送信する方法に行き詰まってはいけません。

5
Michael Kohne

This ページは、他の人が提起したいくつかの問題、つまり、アプリケーションプロトコルごとにアプリケーションプロトコルでデータをカプセル化する必要性に関する情報の良い情報源です。例があり、ネットワークプログラミングのかなり有名な人に由来しています。

2
mrmcgreg

パケットがネットワークデバイスの最大値 [〜#〜] mtu [〜#〜] を超えると、複数のパケットに分割されます。 (ほとんどの機器は1500バイトに設定されていますが、これは必須ではありません。)

パケットの再構築は、アプリケーションに対して完全に透過的でなければなりません。

2
Ben S

ネットワークセグメントごとに異なるMTU値を設定できます。その場合、断片化が発生する可能性があります。詳細については、「 TCP最大セグメントサイズ 」を参照してください

この(デ)フラグメンテーションは、TCPレイヤーで発生します。アプリケーション層には、これ以上パケットはありません。 TCPは、アプリケーションに連続したデータストリームを提供します。

2
lothar

「アプリケーション層」TCPパケット(まあ、本当にセグメント;独自の層のTCPはパケットからはわかりません)は、存在しないため、決して断片化されません。アプリケーション層は、データをバイトストリームとして表示し、信頼性の高い順序で配信されます。

別の方法で考えている場合は、おそらく間違った方法で何かに近づいています。ただし、これは、この上にレイヤーが存在しないことを意味するものではありません。たとえば、この信頼性の高い、順序どおりのバイトストリームで配信される一連のメッセージです。

2
Curt J. Sampson

正しい-これを確認する最も有益な方法は、貴重なツールである Wireshark を使用することです。それを理解するのに時間をかける-私を数回救った、そして良い現実チェックを与えます

1
Jeff

3000バイトのパケットがデフォルトのMTUサイズ1500(イーサネット用)でイーサネットネットワークに入ると、1500バイトの長さの2つのパケットに断片化されます。それは私が考えることができる唯一の時間です。

Wiresharkがこれを確認する最善の策です。私はしばらくそれを使っていて、完全に感銘を受けました

0
Srikar Doddi