TCPプロトコルの機能の詳細な説明

TCPプロトコルの機能

TCP プロトコルには、接続、信頼性の高い伝送、バイト ストリーム指向、全二重という特徴があります。

TCPプロトコルのセグメント形式

ここに画像の説明を挿入
TCP メッセージ = TCP ヘッダー (ヘッダー) + TCP ペイロード

  • 送信元/宛先ポート番号: データがどのプロセスから送信され、どのプロセスに送信されるかを示します。
  • 32ビットシリアル番号/32ビット確認番号:複数のデータを詳細に区別するため
  • 4 ビットのヘッダー長: TCP ヘッダーの特定の長さを記述します (TCP ヘッダーの長さは可変、UDP ヘッダーの長さは可変ではなく、8 バイトで固定)

: 4 ビットヘッダーの長さの単位はバイトではなく 4 バイトであるため、TCP ヘッダーの最大長は 15 * 4 = 60 バイトになります。

  • 6 ビットは予約済み: 将来の拡張を考慮して

ネットワーク プロトコルの拡張とアップグレードは非常に高価な問題ですが、将来 TCP に新しい機能が導入されるときに、これらの予約ビット フィールドを使用できます。

  • 6つのフラグビット
    • URG: 緊急ポインタが有効かどうか
    • ACK: 確認番号が有効かどうか
    • PSH: 受信側アプリケーションに、TCP バッファーからデータをすぐに読み取るように指示します。
    • RST: 相手側が接続の再確立を要求します。RST フラグを持つセグメントをリセット セグメントと呼びます。
    • SYN: 接続を確立する要求。SYN 識別子を同期セグメントと呼びます。
    • FIN: ローカルエンドが閉じられようとしていることを相手に通知します。FIN フラグを持つエンドセグメントを呼び出します。
  • 16 ビットのウィンドウ サイズ:
  • 16 ビット チェックサム: UDP チェックサムと同じ機能: どちらもデータ送信が正しいかどうかを検証しますが、データのセキュリティは保証できません
  • 16 ビット緊急ポインタ: データのどの部分が緊急データであるかを識別します。
  • オプション:オプション前は固定長(20バイト)(計算式:オプション長=ヘッダ長-20バイト)

ヘッダー長の値が 5 の場合、TCP ヘッダー全体の長さが 20 バイト (5x4 バイト) であることを意味します (オプションなしと同等) ヘッダー長の値が 15 の場合、TCP ヘッダー全体の長さが 60 バイト (
15x4 バイト) であることを意味しますバイト)(オプション 40バイト相当)

TCPの原則

確認応答(安全機構)

図例: ここに画像の説明を挿入
A が B にメッセージを送信し、B はそれを受信した後、確認応答メッセージ (ACK) を返します。このとき、A は確認応答を受信すると、送信したデータが B に正常に受信されたことがわかります。

より複雑な状況の
例の図を考えてみましょう。 ここに画像の説明を挿入
ネットワーク上では「後発、先着」の可能性があるため、メッセージの受信順序は変動する可能性があり、「食事に行きますか?: 良くありません」、「勉強に行きます」になります。 ?: 「わかりました」。本来の意味と矛盾します。

前述した後送信先着問題を解決するために、送信データと応答メッセージの両方に番号が付けられます。
画像例: ここに画像の説明を挿入
このように、シリアル番号を使用して、現在の応答メッセージがどのデータに対するものであるかを区別できます。

応答メッセージかどうかはヘッダのACKフラグによって判断され、ACKフラグが1の場合は応答メッセージ、0の場合は応答メッセージではありません。

実際、TCP はバイト指向であるため、TCP のシーケンス番号も次のようになります。バイト番号を付ける

ここに画像の説明を挿入

TCP バイトのシーケンス番号は順番に蓄積され、各 TCP データグラムのヘッダーに埋められるシーケンス番号は、TCP データの最初のバイトのシーケンス番号を記述するだけで済みます。
TCP は最初のバイトのシリアル番号を知っており、TCP メッセージの長さに応じて各バイトのシリアル番号を知るのは簡単です。

確認シーケンス番号の値は、受信データの最終バイトのシーケンス番号 + 1

例: 確認シーケンス番号 1001 の意味
:
1. 1001 未満のすべてのデータが受信されたことが確認されました。
2. A はシリアル番号 1001 から送信を続けます (B は A に 1001 のデータを要求します)

概要: TCP の信頼性の高い送信機能、主要終わっています確認応答メカニズム保証する、を通じて応答メッセージ確認応答)、送信者は送信が成功したかどうかを明確に知ることができ、さらにシリアルナンバーシリアル番号を確認する、複数のデータセットを詳細に区別する場合

タイムアウト再送信(安全機構)

上記の確認応答の説明では、正常に通信が行われている状況のみを説明しており、伝送問題(パケットロスなど)の状況については触れていません

ケース 1: データ損失
ここに画像の説明を挿入

  • ホスト A がホスト B にデータを送信した後、ネットワークの混雑やその他の理由により、データがホスト B に届かない場合があります。
  • ホスト A が一定の時間内に B から確認応答を受信しない場合、ホスト A は再送信します。

2 番目のケース: ACK 損失
ここに画像の説明を挿入
2 番目のケースはデータを再送信するため、ホスト B が大量の重複データを受信する可能性があります。TCP はそれらを重複排除して再配置します。

TCP には「受信バッファ」(受信側のオペレーティング システム カーネル内のメモリのセグメント) などの記憶領域があり、各 TCP ソケット オブジェクトには受信バッファがあります。
ホスト B はホスト A からデータを受信します。実際、B のネットワーク カードはデータを読み取り、B の対応するソケットの受信バッファにデータを置きます。後続のアプリケーション プログラムは getInputStream を使用し、さらに read を使用してホストから読み取ります。受信バッファのデータ。
TCP はデータに従ってこの受信バッファを使用します。シリアルナンバーデータの重複の有無を特定し、重複している場合は後続のデータを破棄し、受信したデータを並べ替えます。

まとめ: 重複排除および並べ替えメカニズム (どちらも TCP ヘッダーのシリアル番号に依存します) の存在により、送信者は ACK が時間通りに到着しないことが判明した場合に限り、データを再送信します。

TCP の確実な送信は、確認応答 + タイムアウト再送によって反映されます。
このうち、確認応答は伝送がスムーズに行われている状況を表し、
タイムアウト再送は伝送に問題がある状況を表します。

接続管理(セキュリティメカニズム)(面接でよくある質問)

通常の状況では、TCP は接続を確立するために 3 回ハンドシェイクを行い、切断するには 4 回手を振る必要があります。

3回の握手

ここに画像の説明を挿入

接続確立フェーズのいくつかの状態:
1.聞く:
相手の接続確立要求を聞き、サーバーの準備ができていることを示し、クライアントはいつでも接続を確立できます。これは、携帯電話の電源を入れるのと同じで、良好な信号があれば、他の人の接続に応答できます。いつでも電話します。

2. SYN_SEND: リクエスト接続に属しており、この時点で送信されるセグメントはデータを運ぶことができません
3. SYN_RECEIVE:相手からのコネクション確立要求を受信しました。

4.設立
接続が確立され、通常の通信が可能になります。これは、電話をかけ、相手が接続されたのと同じです。クライアントがこの状態にある場合、送信された ACK セグメントはデータを伝送できます。

いわゆる 3 方向のハンドシェイクは、本質的には「4 方向」の対話です。
通信中の 2 つの当事者は、それぞれ相手に対して「接続確立」要求を開始し、同時に相手に対して ack で応答します。中央の 2 つのインタラクションを 1 つのインタラクションに結合して、「3 ウェイ ハンドシェイク」を形成できます。

質問 1: 中央の 2 つのインタラクションをマージする必要があるのはなぜですか?
回答: パッケージの廃止に関連しており、パッケージを 1 回分解するよりも 2 回分解する方がコストが高くなります。

質問 2:双方向ハンドシェイクの場合、接続は確立できますか?
答え: いいえ。
最初のハンドシェイク: クライアントがネットワーク パケットを送信し、サーバーがそれを受信します。
サーバーはクライアントの送信能力とサーバーの受信能力が正常であることを知ることができます。
2 番目のハンドシェイク: サーバーがネットワーク パケットを送信し、クライアントがそれを受信します。
クライアントは、クライアントの送受信能力が正常であることを知ることができます。サーバーの送受信機能は正常です。ただし、この時点ではサーバーは送信能力が正常かどうかはわかりません。
3 回目のハンドシェイク: クライアントがネットワーク パケットを再度送信し、サーバーがそれを受信します。
サーバーは、クライアントの送受信機能が正常であることを認識しています。サーバーの送受信機能は正常です。
したがって、双方の送受信能力が正常であるかどうかを確認するために、3 ウェイ ハンドシェイクが必要になります。

三者握手の意味:
1. 通信当事者が互いの「認識」を確立する
2. 通信当事者の送受信能力が正常かどうかを確認する
3. ハンドシェイク プロセス中、両者はハンドシェイク プロセスを完了するためにいくつかの重要なパラメータをネゴシエートする必要があるデータの同期。
接続確立フェーズ

四回手を振った

4 ウェイ ハンドシェイクは 3 ウェイ ハンドシェイクと非常によく似ており、通信の両当事者が相互に切断要求を開始し、その後、相互に応答を返します。
ここに画像の説明を挿入
接続確立フェーズのいくつかの状態:
1. FIN_WAIT_1: クライアントがアクティブに close を呼び出すと、エンド セグメント (FIN) がサーバーに送信され、同時に FIN_WAIT_1 に入ります。

2.CLOSE_WAIT: (受け身クライアントが
積極的に接続を閉じると (close を呼び出す)、サーバーは終了セグメント (FIN) を受信し、サーバーは確認セグメント (ACK) を返し、CLOSE_WAIT に入ります; 3. FIN_WAIT_2:クライアント

が受信するサーバーが終了セグメントを確認 (ACK) したら、FIN_WAIT_2 を入力し、
サーバーからの終了セグメント (FIN) の待機を開始します;
4. LAST_ACK: CLOSE_WAIT を入力した後、サーバーが接続を閉じる準備ができていることを意味します (前のデータを処理する必要があります); サーバーが実際に close を呼び出して接続を閉じると、クライアントに FIN が送信されます。この時点で、サーバーは LAST_ACK 状態に入り、最後の ACK が到着するのを待ちます (この ACK は、 FIN を受け取ったというクライアントの確認)

5. TIME_WAIT: (切断を開始した側に表示されます)
クライアントが積極的に切断すると仮定すると、クライアントが TIME_WAIT 状態になると、4 回手を振ったことと同等になり、クライアントはサーバーからのメッセージを受信します。 セグメントを終了します (FIN) )、TIME_WAIT を入力し、LAST_ACK を発行します。

[TIME_WAIT -> CLOSED] クライアントは、CLOSED 状態に入る前に 2MSL (最大パケット有効期間) 時間待機します。

6. サーバーは FIN に対する ACK を受信し、接続を完全に閉じ、CLOSED 状態に入ります。

TIME_WAITの意味: 4ウェイハンドシェイクは3ウェイハンドシェイクと同じであり、パケットロスも発生します. サーバーが最後のACKを受信しない場合、再送信操作が実行されます. したがって、TIME_WAIT状態は、最後の ACK パケット損失に対処するための一定期間この場合、サーバーによって再送信された FIN を受信した後、クライアントは再送信された FIN に対する ACK で応答できます。

質問 1: 3 ウェイ ハンドシェイクの途中にある 2 つの j インタラクションはマージできるのに、4 つのハンドシェイクはマージできないのはなぜですか?
答え:

  • スリーウェイ ハンドシェイクの 3 者間対話プロセスはピュア カーネル内で完了し、サーバーのシステム カーネルが SYN を受信すると、すぐに ACK と SYN を同時に送信して、それらをマージできます。
  • 4 波ウェーブにおける FIN の開始はカーネルによって制御されませんが、FIN はアプリケーションがソケットの close メソッドを呼び出す (またはプロセスが終了する) ことによってトリガーされ、ACK はカーネルによって制御されます。送信者が送ったFINを受信 その後すぐにACKが返ってきますが、通常両者には時間差があるためマージできません。

質問 2: 考えてみてください。なぜ TIME_WAIT の時間は 2MSL なのでしょうか。?
MSL は TCP メッセージの最大存続期間であるため、TIME_WAIT が 2MSL 持続する場合、
両送信方向の未受信または遅延メッセージ セグメントが確実に消失することができます (そうでない場合、サーバーはすぐに再起動し、メッセージの上位の遅延データからメッセージを受信する可能性があります)。プロセスですが、このデータは間違っている可能性があります);
同時に、理論的には、最後のメッセージが確実に到着することも保証されています (最後の ACK が失われたと仮定すると、サーバーは FIN を再送信します。このとき、クライアントのプロセスは消えていますが、TCP 接続はまだ存在しており、LAST_ACK はまだ再送信できます)。

質問 3: サーバー上に多数の CLOSE_WAIT 状態があります。その理由は何ですか?
回答: サーバーがソケットを正しく閉じなかったため、4 つのハンド ウェーブが正しく完了しませんでした。これはバグです。問題を解決するには、対応する close を追加するだけです

スライディングウィンドウ(効率機構)

上で説明した確認応答戦略では、送信されたデータ セグメントごとに ACK 確認応答が必要です。ACK を受信した後、次のデータ セグメントが送信されます。そうするとパフォーマンスが低下します。

このとき、パフォーマンスを向上させるためにスライディング ウィンドウ機構が使用されます
特定の操作: バッチで送信、バッチで待機、待機時間を使用してデータセットの複数の ACK を待機することで、確認応答の ACK の待機にかかる時間を本質的に削減します。
ここに画像の説明を挿入

ウィンドウサイズ: 確認応答を待たずにデータを送信し続けることができる最大値。上図のウィンドウ サイズは 4000 です。

  • 最初の 4 つのセグメントを送信するときは、ACK を待つ必要はなく、直接送信するだけです。
  • 最初の ACK を受信した後、スライディング ウィンドウは逆方向に移動し、5 番目のセグメントのデータを送信し続けます。

以下に、パケット損失の 2 つのケースについて説明します。
状況 1: データ パケットは到着しましたが、ACK が失われています。
ここに画像の説明を挿入
この場合、ACK の一部が失われたとしても、後続の ACK によって確認できるため、問題はありません。

ケース 2: データ パケットが直接失われます。
ここに画像の説明を挿入

  • メッセージのセグメントが失われた場合、送信者は常に 1001 のような ACK を受信します。これは、1001 ~ 2000 のデータが受信されていないこと、および対応するデータ 1001 ~ 2000 を再送信する必要があることを送信者に通知するためのものです。
  • この時、受信側が1001を受信した後、再度返ってくるACKは7001(2001-7000なので)ですが、受信側は実際に以前に受信して受信バッファに入れています。

上記の仕組みは「高速再送機構」とも呼ばれます。

フロー制御(セキュリティ機構)

フロー制御は送信ウィンドウのサイズに介入するメカニズムです

質問 1: ウィンドウ サイズを制御する理由は何ですか?

  • ウィンドウが大きすぎるため、多くのシステム リソースを消費します
  • ウィンドウが大きすぎるため、ack をまったく待たないと信頼性が保証されません
  • 受信機の処理能力を考慮するため

質問 2: TCP プロトコルのセグメント形式では、16 ビットのウィンドウ サイズは最大ウィンドウ サイズが 64 kb であることを意味しますか?
回答: いいえ、TCP はオプション部分にウィンドウ拡張係数 M を導入しているため、実際のウィンドウ サイズは M だけ左にシフトされたウィンドウ フィールドの値になります。

フロー制御の仕事は、(受信者の受け入れバッファの残りのサイズをチェックすることによって) 受信者の処理能力に応じて送信者の送信レートを調整することです。

送信側は受信側にデータを送信し、受信側は受信バッファの残りのサイズを確認し、この値を ACK メッセージを通じて送信側に返します。送信側は次のラウンドのウィンドウ サイズを確認します。この番号に従って送信します。
ウィンドウ サイズが 0 の場合、送信側は送信を一時停止します。送信一時停止の待機プロセス中、受信側は定期的にウィンドウ検出メッセージを送信します。このメッセージには特定のビジネス データは含まれません。ACK をトリガーしてウィンドウ サイズを問い合わせるだけです。 。

注: ウィンドウ サイズは「送信者」の概念であり、受信者の ack ヘッダーのウィンドウ サイズ フィールドを通じて送信者に伝えられます。

渋滞制御(安全機構)

受信側の処理能力を考慮したフロー制御と、送信時の中間ノードの処理能力を考慮した次に説明する輻輳制御は、両者を合わせて送信側のウィンドウサイズ(小さい方の値)を決定します。

輻輳制御とは、本質的には、実験を通じて適切なウィンドウ サイズを徐々に見つけていくことです。

ここに画像の説明を挿入

  • ラウンド 0 ではウィンドウ サイズが 1 単位で、非常に遅い速度でデータが送信されますが、送信がスムーズであればウィンドウ サイズは 2 倍になります。
  • 初期段階では、初期ウィンドウが比較的小さいため、各ラウンドでパケット損失が発生することなく、ウィンドウ サイズは 2 倍になります (指数関数的に増加します)。
  • 増加率がしきい値に達すると、このときの指数関数的な増加は線形の増加に変換されます (パケット損失がない場合)。
  • 送信中にパケットロスが発生した場合、その時点で送信レートがネットワークの限界に近づいていることを意味し、ウィンドウサイズを小さい値に縮小します(上記の指数関数的増加と線形増加のプロセスを繰り返します)。輻輳ウィンドウは次のようになります。固定
    値ではなく、常に動的に変化します。

TCP は、上記の機能だけではなく、非常に複雑なプロトコルです。TCP 機能について詳しく知りたい場合は、RFC 標準ドキュメントを参照してください。

おすすめ

転載: blog.csdn.net/m0_63904107/article/details/130181386