用語辞典・通信プロトコル

TCP

TCPとは

TCPは、順序制御、再送、流量制御を行い、信頼性のあるバイト列通信を提供するトランスポート層プロトコルです。正式名称はTransmission Control Protocol(トランスミッション・コントロール・プロトコル)で、ティーシーピーと読みます。

通信する二つの端点が接続状態を持ち、送信したバイトへ順序番号を付けます。受信側は届いた範囲を確認応答し、欠けた範囲を送信側が再送します。重複を除き、順番をそろえた連続バイト列をアプリへ渡します。

TCPが守るのはアプリの「メッセージ単位」ではなく、順序付きのバイトストリームです。一回の送信操作が一回の受信操作として同じ境界で届く保証はなく、アプリ側で長さや区切りを定めます。

接続を確立し、バイト列を分割して送り、到着順を直し、欠けた範囲を再送する受信側の空き容量とネットワーク混雑の二つに合わせて送信量を調整する
クライアントとサーバーの三方向矢印で接続を確立し、アプリの連続バイト列を複数セグメントへ分け、異なるIP経路で順不同に到着したものを並べ直し、一つ欠けた区間を確認応答から再送し、輻輳ウィンドウと受信ウィンドウを変化させ、双方向を個別に終了するTCPの図解
図1図の色付き図形はバイト位置の概念表現です。実際のシーケンス番号はセグメント番号ではなく、バイト列中の位置を基準に進みます。

接続、転送、回復、終了を一つの状態機械として扱う

IPが個々のパケットを運び、TCP端点が到着結果を管理する途中のルーターがTCP再送や順序修正を行うわけではない
  1. Open
    3ウェイハンドシェイク

    SYN、SYN+ACK、ACKで双方の初期シーケンス番号と接続可能性を確認する

  2. Segment
    バイト列を区間へ分ける

    MSSと経路条件に合わせてTCPセグメントを作り、IPパケットへ収容する

  3. Acknowledge
    次に必要な位置を返す

    連続して受け取れた範囲を累積ACKで示し、選択確認を使う実装もある

  4. Recover
    損失を再送で補う

    重複ACKや再送タイマーから欠落を推定し、必要な範囲を送り直す

  5. Regulate
    二つの窓で送信量を制御

    受信バッファーとネットワーク混雑の小さい側に合わせ、未確認データ量を抑える

  6. Close
    方向ごとに送信を終える

    FINとACKで各方向を独立に閉じ、異常時はRSTで接続状態を打ち切る

図2接続確立前のデータ送信、同時オープン、半閉鎖など詳細状態があります。基本は双方が状態を同期することです。

接続はIPアドレスとポート番号の組で識別する

TCP接続は通常、送信元IP、送信元ポート番号、宛先IP、宛先ポートの組で区別します。サーバーは待受ポートを持ち、クライアントは一時ポートを選びます。同じサーバーポートへ多数の接続を同時に作れるのは、組全体が異なるためです。

OSではIP版、プロトコル、アドレス、ポートなどを持つ通信端点をソケットとしてアプリへ提供します。TCP自身はURL、ユーザー名、Webページなどアプリの意味を理解しません。

3ウェイハンドシェイクで、双方の初期番号を同期する

開始側はSYNフラグと初期シーケンス番号を送り、待受側はSYNとACKを返し、自分の初期番号と相手番号の受領を示します。開始側がACKを返すと、双方が送受信可能な接続状態になります。

途中でSYNや応答が失われれば再送します。待受していないポートからRSTが返る、ファイアウォールで無応答になるなど、失敗の見え方は異なります。ハンドシェイク成功はアプリの認証や処理成功を保証しません。

シーケンス番号とACKは、バイト位置を管理する

各セグメントは先頭データのシーケンス番号を持ちます。受信側のACKは一般に「この番号の直前まで連続して受け取り、次はここから必要」と累積で示します。後続だけ先に届けばバッファーへ保持し、欠けた位置を待ちます。

SACK(Selective Acknowledgment/セレクティブ・アクノレッジメント)オプションは、連続範囲の先に届いた区間も伝え、送信側が不足部分を絞って再送しやすくします。受信した重複セグメントは順序番号から除外します。

再送タイマーと重複ACKから、損失を推定する

送信側は確認応答までの時間を測り、RTO(Retransmission Timeout/リトランスミッション・タイムアウト)を計算します。期限までACKがなければ再送し、連続タイムアウト時は待ち時間を増やします。

後続セグメントが到着すると同じACKが繰り返され、送信側はタイマーを待たず欠落を推定するfast retransmit(ファスト・リトランスミット)を行えます。ただし遅延、並べ替え、ACK損失もあるため、TCPは直接「パケットが落ちた」という通知だけを受けるわけではありません。

受信ウィンドウは相手の空き、輻輳ウィンドウはネットワークの余裕を表す

receive window(レシーブ・ウィンドウ/受信ウィンドウ)は、受信側が現在受け入れられるバイト量を通知するフロー制御です。アプリが読み取らずバッファーが満ちれば小さくなり、ゼロなら送信側は通常データ送信を待ちます。

congestion window(コンジェスチョン・ウィンドウ/輻輳ウィンドウ)は、送信側がネットワークへ未確認で出せる量を調整します。ACK到着で徐々に広げ、損失やECNを混雑の兆候として縮めます。実際の送信可能量は二つのウィンドウの小さい方に制限されます。

順序保証は、失われた一箇所より後ろの受け渡しを待たせる

後続データがネットワーク上では届いていても、途中のバイトが欠ければTCPは通常、順序どおりの連続ストリームとしてアプリへ渡すため回復を待ちます。これをトランスポート層のhead-of-line blocking(ヘッド・オブ・ライン・ブロッキング)として説明できます。

複数の独立処理を一本のTCPへ載せるアプリでは、一箇所の損失が後続すべてを待たせる場合があります。HTTP/2は一つのTCP上へ多重化するためこの影響を受け、QUICは複数ストリーム間の待ち合わせを減らす設計です。

TCPは暗号化も、アプリデータの正しさも保証しない

TCPチェックサムは伝送中のビット誤りを検出しますが、悪意ある改ざんや相手の身元を暗号学的に保証しません。機密性、認証、完全性にはTLSなどをTCPの上で使います。

ACKは受信側TCPがバイトを受け取ったことを示し、アプリが保存・処理・表示を完了したことまでは示しません。注文受付、ファイル保存、メール配送などの完了確認は、アプリケーションプロトコルが別に返す必要があります。

FINは片方向の終了、RSTは接続状態の打ち切りを示す

TCPは全二重のため、FINで「自分から送るデータは終わり」と片方向を閉じても、反対方向のデータを受け続けられます。双方がFINを送り、それぞれACKを確認して正常終了します。

RSTは存在しない接続へのセグメント、待受のないポート、アプリの異常終了などで接続を直ちにリセットします。途中機器がRSTを生成する場合もあるため、観測位置とシーケンス番号を含めて判断します。

仕様の確認資料:RFC 9293 / STD 7「Transmission Control Protocol」RFC 5681「TCP Congestion Control」RFC 6298「Computing TCP's Retransmission Timer」

関連用語