本文へ移動

インフラ転職コンパス難しいインフラ技術を動画と図解で解説

メニュー

3ウェイハンドシェイクとは?SYN・SYN/ACK・ACKの流れと読み方を図解

動画と記事で学ぶ / IP・通信プロトコル

TCPの3ウェイハンドシェイクをSYN→SYN/ACK→ACKの図とWiresharkで解説。Seq・ACK番号の読み方、SYN再送・接続拒否・ACK欠落の違いまで現場の確認順で整理します。

ここからは、検索目的に合わせて再構成した記事本文を読めます。図解・手順・コマンド例がある場合は本文内で確認できます。

3ウェイハンドシェイクとは、TCP通信を始める前に、クライアントとサーバーがSYN、SYN/ACK、ACKの3つのセグメントを交換して接続を確立する手順です。

言葉だけなら「SYN→SYN/ACK→ACK」で終わります。しかし、実務で本当に役立つのは、なぜ3回必要なのか、シーケンス番号がなぜ+1されるのか、どのパケットで止まると何を疑うのかまで説明できることです。

この記事では、元インフラエンジニアの筆者が、3ウェイハンドシェイクの仕組みを図でほどき、Wiresharkでの見方と通信障害の切り分けまで一つの流れで解説します。

この記事でわかること

  • 3ウェイハンドシェイクを行う目的
  • SYN・SYN/ACK・ACKの意味とパケットの向き
  • シーケンス番号とACK番号が+1される理由
  • Wiresharkで正常・異常を見分ける方法
  • タイムアウト・RST・SYN再送の切り分け方

3ウェイハンドシェイクを理解すると、「TCPポートへ到達できない」のか「接続後のTLSやアプリケーションで失敗した」のかを切り分けやすくなります。

3ウェイハンドシェイクとは

3ウェイハンドシェイク(three-way handshake)は、TCPでデータ通信を開始する前に行う接続確立の手順です。クライアントとサーバーが3つのTCPセグメントを交換し、次の準備を整えます。

  • クライアントからサーバーへ到達できることを確認する
  • サーバーからクライアントへ応答できることを確認する
  • 双方の初期シーケンス番号を交換する
  • MSSやWindow ScaleなどのTCPオプションを交換する
  • 双方が通信状態をESTABLISHEDへ進める

「TCPコネクションを張る」といっても、経路上に専用線が作られるわけではありません。クライアントとサーバーが、送信元IP、送信元ポート、宛先IP、宛先ポートの組み合わせと、送受信する番号をそれぞれ管理する状態を作ります。

TCPとUDPの違い
比較 TCP UDP
通信前の接続確立 3ウェイハンドシェイクを行う 行わない
到達確認・再送 ACKや再送で制御する UDP自体にはない
データの順序 シーケンス番号で管理する UDP自体では保証しない
代表例 HTTP/HTTPS、SSH、メール DNS、音声・映像、監視

3ウェイハンドシェイクの流れ|SYN・SYN/ACK・ACK

例として、クライアントがWebサーバーのTCP/443へ接続する場面を考えます。クライアント側の初期シーケンス番号を1000、サーバー側を5000とします。

3ウェイハンドシェイクのシーケンス図
クライアント
192.0.2.10:52000
TCP接続を開始
サーバー
198.51.100.20:443
① SYN-SENT
SYN Seq=1000 →
LISTEN
← SYN, ACK Seq=5000 Ack=1001
② SYN-RECEIVED
③ ESTABLISHED
ACK Seq=1001 Ack=5001 →
ESTABLISHED

1回目:クライアントがSYNを送る

クライアントは、サーバーの待受ポートへSYNフラグを立てたTCPセグメントを送ります。SYNは「新しい接続を開始したい。こちらの初期シーケンス番号は1000です」という意味です。

  • 送信元:クライアントの一時ポート
  • 宛先:サーバーの待受ポート
  • フラグ:SYN=1、ACK=0
  • シーケンス番号:1000

クライアントの状態はCLOSEDからSYN-SENTへ移ります。ここで応答がなければ、一定時間後にSYNを再送します。

2回目:サーバーがSYN/ACKを返す

サーバーが対象ポートで待ち受けており、接続を受け付けられる場合はSYNとACKの両方を立てて返します。これは「SYNを受け取りました。次は1001を待っています。こちらの初期シーケンス番号は5000です」という応答です。

  • フラグ:SYN=1、ACK=1
  • サーバーのシーケンス番号:5000
  • クライアントへのACK番号:1001

サーバーの状態はLISTENからSYN-RECEIVEDへ移ります。この段階ではまだ接続確立の途中です。

3回目:クライアントがACKを返す

クライアントはサーバーのSYN/ACKを受け取り、ACKを返します。「サーバーの初期シーケンス番号5000を受け取り、次は5001を待っています」という確認です。

  • フラグ:SYN=0、ACK=1
  • クライアントのシーケンス番号:1001
  • サーバーへのACK番号:5001

このACKをサーバーが受け取ると、双方がESTABLISHEDになります。その後、HTTPSならTLSのClient Hello、HTTPならリクエストなど、アプリケーションデータの送受信へ進みます。

3つのTCPセグメントの意味
順番 方向 フラグ 役割
1 クライアント → サーバー SYN 接続要求とクライアント側ISNの通知
2 サーバー → クライアント SYN/ACK SYNの受領確認とサーバー側ISNの通知
3 クライアント → サーバー ACK サーバー側SYNの受領確認

なぜ3回のやり取りが必要なのか

TCPは双方向通信です。クライアントからサーバーへ送るデータと、サーバーからクライアントへ送るデータには、それぞれ独立したシーケンス番号があります。そのため双方が自分の初期シーケンス番号を伝え、相手が受け取ったことを確認する必要があります。

必要な役割は、次の4つです。

  1. クライアントが自分のSYNを送る
  2. サーバーがクライアントのSYNをACKする
  3. サーバーが自分のSYNを送る
  4. クライアントがサーバーのSYNをACKする

サーバーは2と3を一つのSYN/ACKにまとめられるため、合計3セグメントになります。

2回で終えると、サーバーは自分が送ったSYN/ACKをクライアントが受け取ったか確認できません。古いSYNや送信元を偽装したSYNでも、相手が存在すると判断して接続状態を作り続けることになります。3回目のACKには「あなたの開始番号も確かに受け取りました」という役割があります。

シーケンス番号とACK番号の読み方

シーケンス番号(Sequence Number)は、送信するバイト列の位置を表します。ACK番号(Acknowledgment Number)は「ここまで受け取った」ではなく、正確には次に受け取りたいシーケンス番号です。

クライアントがSeq=1000のSYNを送った場合、サーバーはAck=1001を返します。SYNには通常アプリケーションデータがありませんが、TCPのシーケンス空間を1つ消費するためです。同じ理由で、サーバーのSeq=5000に対してクライアントはAck=5001を返します。

ACK番号は「次に欲しい番号」
受信したSYN
Seq=1000
返すACK
Ack=1001

SYNとFINはペイロードがなくても、それぞれシーケンス番号を1つ消費します。

WiresharkでSeq=0と表示される理由

実際の初期シーケンス番号は大きな値ですが、Wiresharkは読みやすくするため、通常は最初の番号を0とする相対シーケンス番号で表示します。その場合、正常な3ウェイハンドシェイクは次のように見えます。

  • SYN:Seq=0
  • SYN/ACK:Seq=0 Ack=1
  • ACK:Seq=1 Ack=1

「本当に0から始まっている」と判断しないでください。パケット詳細の設定で相対表示を外せば、TCPヘッダーの実際の値を確認できます。

3ウェイハンドシェイク中のTCP状態遷移

パケットだけでなく、OSが持つTCPの状態も合わせて見ると理解が深まります。

接続確立までの状態遷移
クライアント

CLOSED

↓ SYN送信

SYN-SENT

↓ SYN/ACK受信・ACK送信

ESTABLISHED

⇄
サーバー

LISTEN

↓ SYN受信・SYN/ACK送信

SYN-RECEIVED

↓ ACK受信

ESTABLISHED

Linuxではss -tn、WindowsではGet-NetTCPConnectionやnetstat -anoで状態を確認できます。SYN-SENTが残っていればクライアントは応答待ち、SYN-RECEIVEDが大量に残っていればサーバーが最後のACKを受け取れていない可能性があります。

SYNで交換するTCPオプション

SYNとSYN/ACKでは、初期シーケンス番号だけでなく、データ転送に使う条件も交換します。パケットサイズや性能問題を調べるときは、次の項目を確認します。

SYNでよく見るTCPオプション
項目 意味 見る場面
MSS 1セグメントで受信できるTCPデータの最大値 断片化、VPN、MTU問題
Window Scale 受信ウィンドウを拡大する倍率 高帯域・高遅延回線の性能
SACK Permitted 欠落部分を選択的に通知できることを示す 再送が多い通信
Timestamps 時刻値を使ったRTT計測など 遅延や再送の解析

MSSは双方が同じ値である必要はありません。各方向で「自分が受信できる上限」を伝えます。また、Window Scaleは接続確立後に突然有効化できるものではなく、SYN段階で合意します。3ウェイハンドシェイクは、後続通信の性能条件を決める場面でもあります。

Wiresharkで3ウェイハンドシェイクを確認する方法

Wiresharkでは、まず送信元・宛先IPとポート番号を確認し、その後にフラグ、Seq、Ack、再送の有無を同じTCPストリームで追います。

基本の表示フィルタ

Wiresharkの表示フィルタ例
# SYNだけを見る
tcp.flags.syn == 1 && tcp.flags.ack == 0

# SYNとSYN/ACKの両方を見る
tcp.flags.syn == 1

# RSTを見る
tcp.flags.reset == 1

# 特定の接続を最初から最後まで追う
tcp.stream eq 0

# 特定のIPとポートに絞る
ip.addr == 198.51.100.20 && tcp.port == 443

正常な通信の確認順序

  1. クライアントからサーバーへSYNが出ている
  2. 逆方向にSYN/ACKが返っている
  3. クライアントがACKを返している
  4. 3つのパケットでIPアドレスとポートの組み合わせが反転している
  5. SeqとAckが相手の番号に対応している
  6. 直後にTLSやHTTPなどのデータが続いている

フラグだけを見て「正常」と決めないことが重要です。別の接続のSYN/ACKを見ている可能性があるため、同じtcp.streamで追います。私は障害調査で、正常系と異常系を同じフィルタ、同じ取得地点で並べ、最初に差が出たパケットを探していました。

どのパケットで止まったかを先に見る

キャプチャの状態 最初に確認すること
SYNだけが再送される 宛先IP・経路・FW・サーバー到達性。戻りのSYN/ACKも確認
SYNにRSTが返る 宛先ポートの待受、送信元・宛先、途中機器による拒否
SYN/ACKまでは見える 最終ACKが返る経路、端末側FW、非対称経路
3回成立後に止まる アプリの要求・応答、TLS、サーバーログ。TCP接続だけでは業務正常とは判定しない

同じ通信を送信元と宛先の両側で観測すると、途中で消えた方向を絞れます。接続状態とシーケンス番号の根拠はRFC 9293(TCP)を参照してください。

3ウェイハンドシェイクの失敗パターンと障害切り分け

通信障害では「接続できない」という結果より、どのパケットまで確認できたかが重要です。SYNの有無、応答の種類、再送方向を分けると、調査範囲を狭められます。

パケットの見え方から原因を切り分ける
見え方 状態 主な確認先
SYNが出ていない 接続処理が始まっていない 名前解決、アプリ、宛先指定、ローカル設定
SYNだけを再送 応答がクライアントへ届かない 宛先IP、経路、ARP、ACL/FW、NAT、サーバー停止、戻り経路
SYNの直後にRST/ACK 宛先まで届いたが接続を拒否 待受プロセス、ポート番号、サーバー側FW
SYN/ACKを再送 サーバーが最後のACKを受け取れない クライアント側FW、NAT、非対称経路、戻り通信
3回完了後に失敗 TCP接続は一度成立 TLS、証明書、HTTP、認証、アプリケーション

SYNを再送してタイムアウトする

クライアントがSYNを繰り返し送っても何も返らない場合、一般に接続タイムアウトになります。パケットが往路で破棄されている、サーバーが停止している、サーバーのSYN/ACKが復路で破棄されているなど、原因は一つではありません。

送信元だけのキャプチャでは「SYN/ACKが返らない」ことまでしか分かりません。可能ならサーバー側やFWでも同時刻に確認し、SYNがどこまで届いたかを追います。

Connection refusedになる

SYNに対してRST/ACKが返ると、アプリケーションでは「Connection refused」「接続が拒否されました」と表示されることがあります。相手まで到達している可能性は高いものの、指定ポートでプロセスが待ち受けていない、またはFWが明示的に拒否している状態です。

サーバーでLinuxならss -lntp、WindowsならGet-NetTCPConnection -State Listenなどを使い、対象IPとポートで待ち受けているか確認します。

SYN/ACKの後にACKが返らない

サーバー側でSYN/ACKの再送が続く場合、クライアントの最後のACKが届いていません。クライアントがSYN/ACKを受信できているか、受信後にACKを送っているかを切り分けます。非対称経路やNAT配下では、往路と復路で異なるFWを通り、セッションとして認識されないことがあります。

3ウェイハンドシェイク後に通信が止まる

ACKまで完了していれば、原因をTCP接続確立より上の層へ移します。HTTPSならTLS Client HelloやServer Hello、HTTPならリクエストとレスポンス、SSHならバージョン交換を確認してください。「SYN/ACKが見えるからアプリも正常」とは限りません。

最短で原因へ近づく確認フロー
① SYNは出たか→② 宛先へ届いたか→③ SYN/ACKは出たか→④ 戻ったか→⑤ ACK後を確認

pingが通るのにTCP接続できない理由

pingはICMP、WebやSSHはTCPです。pingが成功しても、TCP/443やTCP/22がFWで拒否されている、対象ポートでアプリが待ち受けていない、NATルールがないといった問題は残ります。pingの成功はIP到達性を確認する一材料であり、TCPポートの疎通を保証しません。

3ウェイハンドシェイクとSYNフラッド攻撃

サーバーはSYNを受け取ってSYN/ACKを返すと、最後のACKを待つ半接続状態を一定時間保持します。この仕組みを悪用し、大量のSYNを送り続けて接続待ちの領域を消費させる攻撃がSYNフラッドです。

監視では、SYN-RECEIVEDの増加、SYNに対して完了するACKの割合、特定送信元からの急増、SYN/ACK再送を確認します。対策にはSYN Cookie、接続キューやタイムアウトの調整、FW・ロードバランサーでのレート制御などがあります。ただし、正常なアクセス急増や復路障害でも似た見え方になるため、パケット数だけで攻撃と断定しません。

3ウェイハンドシェイクと4ウェイハンドシェイクの違い

3ウェイハンドシェイクは接続を始める手順です。一方、TCP接続を正常に終了するときは、一般にFINとACKを4回交換します。

接続開始と終了の違い
比較 3ウェイハンドシェイク 4ウェイハンドシェイク
目的 TCP接続の確立 TCP接続の正常終了
主なフラグ SYN、ACK FIN、ACK
基本の流れ SYN → SYN/ACK → ACK FIN → ACK → FIN → ACK
回数が違う理由 サーバーがSYNとACKをまとめられる 各方向を独立して閉じるため

TCPは全二重通信なので、一方が送信を終えても、もう一方はデータを送り続けられます。そのため終了時は、両方向を個別に閉じるのが基本です。RSTはこの正常終了とは異なり、接続を即座に打ち切るために使われます。

3ウェイハンドシェイクのよくある質問

3ウェイハンドシェイクを一言で説明すると?

TCP通信を始める前に、クライアントとサーバーがSYN、SYN/ACK、ACKを交換し、双方の初期シーケンス番号と通信可能性を確認して接続を確立する手順です。

SYNとACKは何の略ですか?

SYNはSynchronize、ACKはAcknowledgmentの略です。SYNはシーケンス番号を同期して接続を開始する意思を示し、ACKは受信確認と次に期待するシーケンス番号を示します。

なぜACK番号はシーケンス番号より1大きいのですか?

ACK番号は次に受け取りたい番号を表し、SYNがTCPのシーケンス空間を1つ消費するためです。Seq=1000のSYNを受け取った側は、Ack=1001を返します。

UDPでも3ウェイハンドシェイクを行いますか?

行いません。UDPはコネクションレス型であり、UDP自体にはTCPのSYN、ACK、再送制御、順序保証がありません。必要な確認は上位のアプリケーションが独自に実装します。

HTTPSでは3ウェイハンドシェイクを何回行いますか?

基本的に新しいTCP接続ごとに1回です。その後にTLSハンドシェイクが続きます。ただし、接続の再利用やHTTP/2・HTTP/3などにより、Webページ上のリクエスト数とTCP接続数は一致しません。HTTP/3はUDP上のQUICを使うため、TCPの3ウェイハンドシェイクは行いません。

3ウェイハンドシェイクの途中でパケットが失われたら?

送信側は応答を待ち、タイムアウトするとSYNまたはSYN/ACKを再送します。規定回数で確立できなければ接続は失敗します。Wiresharkでは再送元と応答が消えた方向を確認します。

3ウェイハンドシェイクが完了すればアプリも正常ですか?

いいえ。分かるのは、その時点でTCP接続が成立したことです。TLS証明書、認証、HTTPエラー、アプリケーション停止などは別に確認する必要があります。

3ウェイハンドシェイクとあわせて、ポート番号、経路、パケットキャプチャを理解すると、TCP障害を一連の流れで追えるようになります。

まとめ:3パケットの役割と止まった場所を読む

3ウェイハンドシェイクは、クライアントのSYN、サーバーのSYN/ACK、クライアントのACKでTCP接続を確立します。双方が初期シーケンス番号を伝え、相手が受け取ったことを確認するため、3回の交換が必要です。

障害時は「接続できない」で止めず、SYNが出たか、宛先へ届いたか、SYN/ACKが返ったか、最後のACKが届いたかを順に確認してください。3回完了後なら、TLSやアプリケーション層へ調査を進めます。この切り分けができると、TCP障害の報告と初動が大きく変わります。

このテーマを続けて学ぶ

最近の記事
ピックアップ