TCPとは
TCP(Transmission Control Protocol)は、インターネットで標準的に利用されている通信プロトコルです。
OSI参照モデルにおいてはトランスポート層で動作し、ネットワーク層のIPとアプリケーション層以上のプロトコル(HTTP、FTP、メールなど)の橋渡しをする役割を持ちます。
TCPの特徴
| 特徴 | 説明 |
|---|---|
| 信頼性 | 確認応答や再送制御によりデータが正しく届くように保証します |
| 順序制御 | データがバラバラに届いても正しい順番に並べ替えます |
| コネクション型 | 通信を開始する前に通信路を確立します(3ウェイハンドシェイク) |
| UDPとの違い | TCPは信頼性重視、UDPは速度やリアルタイム性重視 |
ポート番号とは
ポート番号とは、コンピュータが通信を行う際に「どのアプリケーションに渡すか」を識別するための番号です。IPアドレスで「どのコンピュータか」を決め、ポート番号で「どのアプリケーションか」を決めます。
ポート番号の分類
| 種類 | 範囲 | 主な用途 | 例 |
|---|---|---|---|
| ウェルノウンポート番号 | 0~1023 | よく知られたアプリ用に予約 | HTTP=80, HTTPS=443, SMTP=25 |
| 登録済みポート番号 | 1024~49151 | 一般アプリや独自アプリ | MySQL=3306, RDP=3389 |
| ダイナミックポート番号 | 49152~65535 | クライアント側アプリが自動利用 | Webブラウザ利用時に割り当て |
通信の流れ(Webブラウザの例)
- クライアントPCがWebサーバへ接続要求を送信(宛先ポート番号=80)
- Webサーバがリクエストを受信し、応答を返す
- クライアントPC側には動的ポート番号(例:54321)が割り当てられる
- サーバはその番号を宛先として応答を返すため、ブラウザごとに正しく通信が届く
複数のブラウザを開いている場合でも、それぞれに異なる動的ポート番号が割り当てられるため通信が混在することはありません。
TCPヘッダのフォーマット
TCPセグメント(TCPパケット)は「TCPヘッダ」と「TCPペイロード」で構成されます。
- TCPヘッダ:制御情報を格納する部分
- TCPペイロード:実際に運ぶデータ部分(例:HTTPデータなど)
TCPヘッダの各フィールド
| フィールド | ビット数 | 説明 |
|---|---|---|
| 送信元ポート番号 | 16 | 通信を開始したアプリケーションのポート番号 |
| 宛先ポート番号 | 16 | 通信相手のアプリケーションを特定するポート番号 |
| シーケンス番号 | 32 | データの順序を示す番号 |
| 確認応答番号 | 32 | 相手から受け取ったシーケンス番号+データサイズ |
| データオフセット | 4 | TCPヘッダの長さを示す値 |
| 予約 | 3 | 将来の拡張用(現在は0) |
| コントロールフラグ | 9 | TCPの動作を制御するビット(詳細は後述) |
| ウィンドウサイズ | 16 | 受信側が一度に受け取れるデータ量 |
| チェックサム | 16 | TCPヘッダとデータのエラーチェック |
| 緊急ポインタ | 16 | URGフラグが立っている場合のみ有効。緊急データの位置を示す |
| オプション | 可変長 | MSS決定など性能向上のために利用される |
| パディング | 可変長 | TCPヘッダの長さを32ビットの整数倍に調整 |
コントロールフラグの詳細(9ビット)
TCPの制御を行うための9種類のフラグがあります。必要に応じて「1(ON)」に設定されます。
| フラグ | 意味 |
|---|---|
| NS | 輻輳制御保護(ECN-nonce) |
| CWR | 輻輳ウィンドウ縮小(Congestion Window Reduced) |
| ECE | ECN-Echo(輻輳通知の応答) |
| URG | 緊急データが含まれていることを示す |
| ACK | 確認応答番号が有効であることを示す |
| PSH | 受信データを即座にアプリケーションへ渡す |
| RST | 異常時にコネクションを強制切断する |
| SYN | コネクション確立の要求 |
| FIN | コネクション終了の要求 |
ポイント
TCPヘッダに含まれる情報は、以下のようなTCPの特徴的な仕組みで活用されています。
- ポート番号の利用(アプリケーション識別)
- コネクションの確立・維持・切断
- 順序制御(シーケンス番号)
- 再送制御(確認応答番号)
- ウィンドウ制御・フロー制御(通信速度や量を調整)
TCP – コネクションの確立(3ウェイハンドシェイク)
TCPは「コネクション型通信」であり、データ送信前に必ず通信路を確立します。
この仕組みを3ウェイハンドシェイクと呼びます。
| ステップ | SYN | ACK | 説明 |
|---|---|---|---|
| ① ホストA → ホストB | 1 | 0 | 接続要求(SYN=1)。シーケンス番号を送る |
| ② ホストB → ホストA | 1 | 1 | 接続要求+応答(SYN=1, ACK=1)。相手番号に+1した値を返す |
| ③ ホストA → ホストB | 0 | 1 | 応答(ACK=1)。これで接続が確立 |
SYNは「同期要求」、ACKは「確認応答」を意味します。
TCP – コネクションの切断(4ウェイハンドシェイク)
切断は一方的ではなく、双方がやり取りを行ってから終了します。そのため4回のやりとりが必要です。
| ステップ | FIN | ACK | 説明 |
|---|---|---|---|
| ⑧ ホストB → ホストA | 1 | 0 | 切断要求(FIN=1)。送信が終わったことを通知 |
| ⑨ ホストA → ホストB | 0 | 1 | 応答(ACK=1)。切断要求を受け入れる |
| ⑩ ホストA → ホストB | 1 | 0 | 自分も切断要求(FIN=1)を送る |
| ⑪ ホストB → ホストA | 0 | 1 | 応答(ACK=1)。通信終了 |
TCP – データ送受信の流れ
コネクション確立後、データはシーケンス番号と確認応答番号によって管理されます。
例えば、ホストAが100バイト送ると、ホストBは「シーケンス番号+100」の確認応答を返し、次のデータを正しく受信できるようにします。
TCP – MSS(Maximum Segment Size)
3ウェイハンドシェイクで交換される情報のひとつにMSSがあります。これは1つのTCPパケットで送れるデータの最大値を表します。イーサネットでは通常1460バイトがMSSとなります。ホストAが1460、ホストBが2000を通知した場合、小さい方の1460が採用されます。
例として14600バイトを送信する場合、10個のTCPパケットに分割して送られます。
TCPの状態遷移とは
TCPは、通信の開始(接続確立)、通信中(データ転送)、通信の終了(切断)において「状態(ステート)」を持っています。
この状態は「3ウェイハンドシェイク」「4ウェイハンドシェイク」のやりとりの中で変化していきます。
主な状態(ステート)の説明
| ステート | 説明 |
|---|---|
| CLOSED | 未使用状態のTCPポート。クライアントが最初にアクションを起こす前の状態 |
| LISTEN | 待ち受け状態。サーバが接続要求(SYN)を待機している状態 |
| SYN_SENT | クライアントがSYNを送信したが、ACKをまだ受信していない状態 |
| SYN_RECEIVED | サーバがSYNを受信したが、ACKをまだ受信していない状態 |
| ESTABLISHED | コネクションが確立し、実際に通信している状態 |
| FIN_WAIT | 自分から接続終了を開始し、FINを送った後の状態 |
| CLOSE_WAIT | 相手からFINを受け取り、まだ自分の終了処理をしていない状態 |
| LAST_ACK | 自分もFINを送信して、最後のACKを待っている状態 |
| TIME_WAIT | 相手からの最後のパケットを確認し、一定時間待機してからCLOSEDに戻る状態 |
状態遷移の流れ(イメージ)
- 通信確立(3ウェイハンドシェイク)
クライアント:CLOSED → SYN_SENT → ESTABLISHED
サーバ:LISTEN → SYN_RECEIVED → ESTABLISHED - 通信終了(4ウェイハンドシェイク)
アクティブ側(終了を開始した側):ESTABLISHED → FIN_WAIT → TIME_WAIT → CLOSED
パッシブ側(終了要求を受けた側):ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED
実際の確認方法
パソコンのコマンドプロンプトやターミナルで、現在のTCP接続がどの状態にあるか確認できます。
- Windows:
netstat - Linux:
netstat -at
これにより、使用中のTCPポートと状態が表示されます。
TCP – 信頼性の確保(順序制御)
TCPは送信するすべてのパケットに シーケンス番号 を付与します。
これにより、受信側は「受け取ったデータが全体のどの位置にあるか」を判断できます。
例えば、ホストAからホストBに2600バイトのデータを送信する場合、MSS(最大セグメントサイズ)が1300バイトだと、データは次のように分割されます。
| パケット | データサイズ | シーケンス番号 |
|---|---|---|
| 1番目 | 1300バイト | 1~1300 |
| 2番目 | 1300バイト | 1301~2600 |
ホストBはシーケンス番号を基にデータを並べ直すため、順番通りに届かなくても元の2600バイトに正しく復元できます。
TCP – 信頼性の確保(再送制御)
TCPでは、送信したデータが確実に届いたことを ACK(確認応答) で確認します。
- ホストAがホストBへデータを送信
- ホストBがデータを受け取るとACK番号を返す
- ACKが返らなければ、送信側(ホストA)は「途中でパケットが失われた」と判断し、データを再送
この仕組みにより、ネットワークが不安定でもデータが欠けることなく送信されます。
初心者向けイメージ
- 順序制御:データに「通し番号」をつけるので、ジグソーパズルのピースのように元通りに並べられる。
- 再送制御:「届いたよ」の返事が来なければ、送り直す。宅配便で「配達完了通知」が届かないと再配送するイメージ。
TCP – 通信効率の向上(ウィンドウ制御)
TCPでは、ACKによる確認応答によって信頼性を確保していますが、1パケットごとにACKを待っていては通信速度が遅くなります。
そこで「ウィンドウサイズ」という仕組みを利用し、まとめてデータを送信できるようにしています。
ウィンドウサイズとは、一度にACKを待たずに送れるデータ量のことです。
例えば、3900バイトのデータを送信する場合、ウィンドウサイズが3900ならACKを待たずに3900バイトを一度に送信できます。
さらに効率を高めるために「スライディングウィンドウ」という仕組みが使われます。
受信側がデータを受け取ってACKを返すと、その分だけ送信可能なウィンドウが前にスライドします。
送信側はそのACKを待つことなく、連続してウィンドウサイズ分のデータを送り続けることができます。
これにより、待ち時間を減らして高速な通信が可能になります。
TCP – 通信効率の向上(フロー制御)
フロー制御は、受信側の処理能力に応じて送信量を調整する仕組みです。
多数の送信側ホストが同時にデータを送ると、受信側は処理しきれなくなることがあります。
この場合、受信側はウィンドウサイズを小さくして通知し、送信側に送信量を減らすよう伝えます。
受信側が再び処理可能になれば、ウィンドウサイズを大きくして通知します。
ウィンドウ制御は効率を高める仕組みであり、フロー制御は受信側が過負荷にならないように守る仕組みです。
初心者向けイメージ
ウィンドウ制御=「まとめて荷物を送る許可。届いた分だけ窓を開けて次を送れる」
フロー制御=「受け取る側の余裕に合わせて荷物の量を調整する」