1.

TCP 完全ガイド(3ウェイハンドシェイク / コネクション型 / 信頼性 / 輻輳制御 / ヘッダ / UDP との違い)

編集
この記事の要点
  • TCP(Transmission Control Protocol)コネクション型・信頼性ありのトランスポート層プロトコル
  • 通信開始時に 3 ウェイハンドシェイク(SYN → SYN+ACK → ACK)でコネクション確立
  • シーケンス番号 / 確認応答 / 再送制御でパケットの欠落・順序逆転を補正
  • フロー制御(ウィンドウ)輻輳制御(CUBIC / BBR 等)で帯域を制御
  • UDP(コネクションレス・信頼性なし)と対照的。Web(HTTP/1.1, HTTP/2)/ メール / SSH などで広く使われる

TCP とは

TCP(Transmission Control Protocol)は、TCP/IP プロトコルスタックのトランスポート層で動作する代表的なプロトコルです。アプリケーション間で仮想的な「通信路(コネクション)」を張り、データを順序通り・欠落なく届けることを保証します。

TCP と UDP の比較

項目TCPUDP
接続形態コネクション型コネクションレス型
信頼性あり(再送・順序保証)なし(欠落・順序逆転OK)
順序保証ありなし
フロー制御あり(ウィンドウ)なし
輻輳制御ありなし
オーバーヘッド大(ヘッダ最小 20 バイト)小(ヘッダ 8 バイト)
代表用途HTTP/HTTPS / メール / SSH / FTPDNS / VoIP / 動画ストリーミング / ゲーム

3 ウェイハンドシェイク(コネクション確立)

クライアントとサーバーは通信開始前に 3 段階のやり取りでコネクションを張ります。

段階送信元送信先フラグ
1クライアントサーバーSYN(seq=x)
2サーバークライアントSYN + ACK(seq=y, ack=x+1)
3クライアントサーバーACK(ack=y+1)

これでお互いの初期シーケンス番号を交換し、以後は番号でデータの順序・欠落を判定します。

4 ウェイハンドシェイク(切断)

切断は両方向のFIN / ACKを交わす 4 段階。これにより、片方向だけ閉じる「ハーフクローズ」も表現できます。

  1. クライアント → サーバー: FIN
  2. サーバー → クライアント: ACK
  3. サーバー → クライアント: FIN
  4. クライアント → サーバー: ACK(TIME_WAIT 後に解放)

TCP ヘッダ構造

フィールドサイズ意味
送信元ポート / 宛先ポート各 16 ビットアプリケーション識別
シーケンス番号32 ビット送信バイトの通し番号
確認応答番号32 ビット次に受信したいバイトの番号
データオフセット4 ビットヘッダ長(32 ビット単位)
制御フラグ各 1 ビットSYN / ACK / FIN / RST / PSH / URG など
ウィンドウサイズ16 ビット受信可能なバイト数
チェックサム16 ビット誤り検出
緊急ポインタ16 ビットURG 時の境界
オプション0-40 バイトMSS / SACK / Window Scale / Timestamp 等

信頼性の仕組み

仕組み概要
シーケンス番号各バイトに通し番号。受信側は順序を復元・重複を排除
確認応答(ACK)受信側が「次にこの番号が欲しい」と通知
再送タイマー / 高速再送ACK が来なければ再送。3 回 Duplicate ACK で即時再送
SACK(Selective ACK)飛び飛びの欠落を正確に通知できる拡張
チェックサムヘッダ + ペイロードのビット誤り検出

フロー制御(ウィンドウ)

受信側のバッファ容量をヘッダのウィンドウサイズで広告し、送信側はそれを超えて送らない仕組みです。大量送信中でも受信側を溢れさせないように制御します。高遅延・高帯域路ではWindow Scaleオプションで上限を 16 ビットを超えて拡張します。

輻輳制御(ネットワーク全体の混雑回避)

ネットワーク全体が詰まらないよう、送信側は輻輳ウィンドウ(cwnd)を管理します。

段階動作
スロースタートcwnd を指数的に増加
輻輳回避閾値超過後は加算的に増加
パケット喪失検知cwnd を縮小(アルゴリズムにより半減等)

代表アルゴリズム: Reno / NewReno / CUBIC(Linux 既定)/ BBR(Google 提唱)。BBR は喪失ではなく帯域 × RTT を測って制御するため、高 RTT 環境で性能が出やすい。

TCP コネクションの状態遷移

状態意味
LISTENサーバが接続待ち
SYN_SENTクライアント: SYN 送信済み
SYN_RECEIVEDサーバ: SYN+ACK 送信済み
ESTABLISHED確立済み(データ転送中)
FIN_WAIT_1 / 2能動切断側
CLOSE_WAIT受動切断側(アプリの close 待ち)
TIME_WAIT遅延パケット排他のため一定時間待機(通常 2MSL)
CLOSED解放済み

ss -tan / netstat -an でこれらの状態を観察できます。大量の TIME_WAITCLOSE_WAIT 滞留は典型的な性能問題のシグナルです。

TCP を使う代表的なプロトコル

用途ポートプロトコル
Web80 / 443HTTP / HTTPS(HTTP/3 は UDP+QUIC)
メール送信25 / 587 / 465SMTP / SMTPS
メール受信110 / 143 / 995 / 993POP3 / IMAP(+ TLS)
リモート操作22SSH
ファイル転送20 / 21FTP
DB3306 / 5432 / 1521 などMySQL / PostgreSQL / Oracle

TCP/IP モデル内の位置

代表プロトコル
アプリケーション層HTTP / SMTP / DNS / SSH
トランスポート層TCP / UDP
インターネット層IP / ICMP
ネットワークインターフェース層Ethernet / Wi-Fi

パフォーマンスに効くチューニングポイント

項目内容
MSS / MTU1 セグメントの最大バイト。MTU 1500 環境では MSS=1460 が一般的。VPN / トンネル経由ではフラグメント / PMTUD に注意
Window Scale高速・高遅延回線では必須。Linux はデフォルトで有効
SACK欠落時の再送効率を上げる。両端で有効化
Delayed ACK / Nagle小パケット連送を抑制するが、対話アプリでは遅延の原因に。TCP_NODELAY で無効化検討
tcp_tw_reuse / fin_timeout大量 TIME_WAIT を再利用する Linux のチューニング

パケットキャプチャでの観察

tcpdumpWireshark で TCP の挙動を可視化できます。3 ウェイハンドシェイク失敗、再送、Window 0 通知、RST などの兆候から障害切り分けが可能です。

# 80 番への通信を可視化
sudo tcpdump -i any -nn 'tcp port 80' -c 50

# SYN だけ抽出
sudo tcpdump -i any -nn 'tcp[tcpflags] & tcp-syn != 0' -c 20

# 再送の集計(ss コマンド)
ss -i state established '( dport = :443 or sport = :443 )' | grep -E 'retr|cwnd'

HTTP/2 と HTTP/3 の違い

HTTP/2 までは TCP の上で動きますが、HTTP/3 は UDP の上の QUIC を採用しました。理由は TCP のHoL ブロッキング(1 つのパケット欠落で全ストリームが詰まる)回避と、初回ハンドシェイクの高速化です。とはいえ通常のサーバアプリ・データベース・SSH などは引き続き TCP が主役です。

関連

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. TCP
  2. UDP

最近更新/作成されたページ