TCPの仕組みを深く理解しよう
ストーリー
「DBの調査はできるようになったな。ところで、DBサーバーに接続できないトラブルが起きたとき、どう対応する?」
「えっと...ネットワークの問題ですよね。L0でIPアドレスやDNS、HTTPは学びました」
「基礎は知ってるな。じゃあ次は、通信の信頼性を支えるTCPの仕組みを深く理解しよう。これがわかると、接続トラブルの原因を特定できるようになる」
TCPとは(復習と深掘り)
TCP(Transmission Control Protocol)は、信頼性のある通信を実現するプロトコルです。
L0で学んだこと
- TCPはトランスポート層のプロトコル
- データを確実に届ける仕組み
L1で深掘りすること
- 3ウェイハンドシェイクの詳細
- 接続状態の遷移
- 再送制御の仕組み
3ウェイハンドシェイク
TCPで通信を開始するとき、クライアントとサーバーは3回のやりとりで接続を確立します。
クライアント サーバー
| |
|--- SYN (接続要求) -------->| ステップ1
| |
|<-- SYN-ACK (要求受理) -----| ステップ2
| |
|--- ACK (確認応答) -------->| ステップ3
| |
|====== 接続確立 ============|
| |
|--- データ送受信 ----------->|
各ステップの詳細
| ステップ | パケット | 説明 |
|---|---|---|
| 1 | SYN | クライアントが「接続したい」と要求 |
| 2 | SYN-ACK | サーバーが「OK、こちらも接続したい」と応答 |
| 3 | ACK | クライアントが「了解」と確認 |
なぜ3回? お互いが「送信」と「受信」の両方ができることを確認するためです。2回だと、サーバーの送信能力をクライアントが確認できません。
TCP接続の状態
接続にはいくつかの状態があります。netstat や ss コマンドで確認できます。
主要な状態
| 状態 | 説明 |
|---|---|
| LISTEN | 接続待ち(サーバー側) |
| SYN_SENT | SYN送信済み、応答待ち(クライアント側) |
| SYN_RECEIVED | SYN-ACK送信済み、ACK待ち(サーバー側) |
| ESTABLISHED | 接続確立、通信中 |
| FIN_WAIT_1 | 切断要求(FIN)送信済み |
| FIN_WAIT_2 | 切断要求の確認応答受信済み |
| TIME_WAIT | 切断後の待機(一定時間後に消滅) |
| CLOSE_WAIT | 相手から切断要求を受信 |
| CLOSED | 接続なし |
接続状態の確認コマンド
bash
# 現在のTCP接続一覧
ss -tn
# LISTEN状態のポートを表示
ss -tln
# 特定のポートの接続状態
ss -tn | grep :3306 # MySQL
ss -tn | grep :5432 # PostgreSQL接続の切断(4ウェイハンドシェイク)
接続の終了は4回のやりとりで行います。
クライアント サーバー
| |
|--- FIN (切断要求) -------->| ステップ1
|<-- ACK (確認) ------------| ステップ2
| |
|<-- FIN (切断要求) ---------| ステップ3
|--- ACK (確認) ------------>| ステップ4
| |
|====== 接続終了 ============|
再送制御
データが途中で失われた場合、TCPは自動的に再送します。
クライアント サーバー
| |
|--- データ1 --------------->| → ACK受信
|<-- ACK -------------------|
| |
|--- データ2 ----X (消失) | → タイムアウト
| |
|--- データ2 (再送)-------->| → ACK受信
|<-- ACK -------------------|
再送に関する設定
| パラメータ | 説明 |
|---|---|
| RTO(Retransmission Timeout) | 再送までの待ち時間 |
| 最大再送回数 | 何回まで再送を試みるか |
| RTT(Round Trip Time) | パケットの往復時間 |
TCPの再送制御があるおかげで、途中でパケットが失われても、アプリケーションはそれを意識する必要がありません。
トラブルシューティングへの活用
接続できない場合のチェックポイント
| 状態 | 可能性のある原因 |
|---|---|
| SYN_SENT が続く | サーバーが応答していない / ファイアウォールでブロック |
| ESTABLISHED にならない | ハンドシェイクの途中で失敗 |
| TIME_WAIT が大量 | 短時間に大量の接続を作って閉じている |
| CLOSE_WAIT が大量 | アプリケーションが接続を閉じていない(リソースリーク) |
まとめ
| ポイント | 内容 |
|---|---|
| 3ウェイハンドシェイク | SYN → SYN-ACK → ACK で接続確立 |
| 接続状態 | LISTEN, ESTABLISHED, TIME_WAIT 等 |
| 4ウェイハンドシェイク | FIN → ACK → FIN → ACK で切断 |
| 再送制御 | パケット消失時に自動的に再送 |
| トラブルシューティング | ss コマンドで接続状態を確認 |
チェックリスト
- 3ウェイハンドシェイクの3ステップを説明できる
- 主要なTCP接続状態を理解した
- ss コマンドで接続状態を確認できる
- 再送制御の仕組みを理解した
次のステップへ
TCPの仕組みを深く理解しました。 次のセクションでは、TCPと対になるUDPの特徴と使い分けを学びます。
推定読了時間: 20分