動画と記事で学ぶ / IP・通信プロトコル
TCPの3ウェイハンドシェイクを初学者向けに解説。SYN・ACKの意味、3回やり取りする理由、SeqとAckの計算、図とWiresharkの読み方を順に説明します。
ここからは、記事でゆっくり確かめましょう。図や操作の例を見ながら、気になるところから読み進めてください。
SYN、SYN/ACK、ACKの順番は覚えた。でも、なぜ3回もやり取りするのか。最初は、PCとサーバーがお互いの接続開始を受け取り、それぞれが使う番号を知らせ合う手順として見てください。
この記事では、図の矢印を一本ずつ追ってからSeq・Ackの数字を読みます。最後に、返事がない場合と接続後に失敗する場合を分けます。3つの名前が、キャプチャで通信を調べる手掛かりになるところまで進めましょう。

SYN・SYN/ACK・ACKを、1本ずつ追う
最初のSYNは、PCからの「接続を始めたい」という通知です。このとき、自分が使う開始番号も伝えます。サーバーはSYN/ACKでそれを受け取ったことを知らせ、自分の開始番号も送ります。
PCが最後のACKを送ると、サーバー側の開始も受け取ったと伝わります。一方が呼びかけ、もう一方が答えるだけでなく、両側の開始を確認するので3回になります。
用語の補足:フラグって何?
TCPのヘッダーにある、通信の目的を示す印です。SYNは接続開始、ACKは確認番号が有効であること、RSTは接続の拒否や中断などを表します。SYNとACKは同じパケットで両方立つことがあります。
| 順番 | クライアント | サーバー |
|---|---|---|
| SYN送信後 | SYN-SENTで応答待ち | 接続要求を受信 |
| SYN/ACK送信後 | 受信し、有効ならESTABLISHEDへ | SYN-RECEIVEDでACK待ち |
| 最後のACK受信後 | データを送れる状態 | 有効なACKでESTABLISHEDへ |
状態名もこの経過に対応します。PCのSYN-SENTは返事待ち。サーバーのSYN-RECEIVEDは最後のACK待ちです。PCは有効なSYN/ACKを受けてESTABLISHEDへ進み、サーバーは最後の有効なACKを受けて進みます。両側の状態が変わる瞬間は同じではありません。
図は配線を表す構成図ではなく、送受信の順番を表しています。最後のACKにデータが付く場合もありますが、まずは通常の開始手順と、どちらが何を確認したかを押さえれば十分です。
仕様の確認:RFC 9293:接続確立。
Seqは送る位置、Ackは次に欲しい位置
Seqは、送るデータがどの位置から始まるかを表す番号です。Ackは、相手から次に受け取りたい位置を表します。「1000を受け取ったからAckも1000」とはならない点が、最初に迷うところです。
図のPCはSeq=1000でSYNを送っています。SYNは開始の印として番号を1つ使うので、サーバーはAck=1001を返します。サーバーのSYNが7000なら、PCはAck=7001で応じます。
| 送信内容 | 次に期待する番号 |
|---|---|
| Seq=1000 / SYNのみ | 1001 |
| Seq=1001 / データ100バイト | 1101 |
| Seq=1101 / ACKのみ | 1101のまま |
| Seq=1101 / FINのみ | 1102 |
データでは長さの分だけ進みます。Seq=1001から100バイトを送ると、受信側が次に欲しい位置は1101です。50バイトなら50進む、と考えると表の計算を追えます。番号は送受信それぞれにあり、両方向を一つの数字として足し合わせません。
データのないACKだけでは位置は進みません。接続終了に使うFINはSYNと同じく1つ使います。Ackが何を確認した数字かを読むには、直前に送ったデータの長さと、SYN・FINの有無を合わせて見る必要があります。
Wiresharkは、同じ接続だけに絞って見る
キャプチャには、同じサーバーへの別の接続も混ざります。最初から一覧を全部読むより、対象のIPとポートで絞り、その中の一本のTCP接続を選びます。
下のフィルターは、サーバー172.27.92.25の443番を調べる例です。tcp.streamは接続ごとの識別に使えますが、0が目的の接続とは限りません。実際に観測した接続の番号を選びます。
用語の補足:キャプチャとログは何が違う?
キャプチャは、観測した場所を通るパケットを記録します。ログは装置やアプリが記録した出来事です。どちらも、記録した場所・時刻・取得条件を確かめて読みます。
ip.addr == 172.27.92.25 && tcp.port == 443
tcp.stream == 0
tcp.flags.syn == 1
tcp.flags.reset == 1
絞ったら、まずSYNを探し、反対方向のSYN/ACK、その後のACKへ進みます。別の接続のACKを拾うと、順番も番号も合わなくなるので、IPと両側のポートが対応しているかを見ます。
WiresharkでSeqが0、Ackが1に見えるのは、開始を0として表示する相対番号のことがあります。実際の開始番号が0とは限りません。表示方法をそろえれば、相対番号でも「SYNの次は1」「100バイトなら100進む」と同じ読み方ができます。
仕様の確認:Wireshark公式:TCP Analysis。
返事がない?拒否された?止まった場所を分ける
SYNを何度送っても返事がない場合、分かるのは観測地点では応答が見えていないということです。すぐにサーバー故障と決めると、途中のFWや戻り経路を見落とします。
PC側でSYNを見つけたら、サーバー側へ届いているかを調べます。届いているなら、応答を出したか、その応答がPCまで戻ったかへ進めます。両端の同じ接続を比べると、調査する区間を狭められます。
| キャプチャの見え方 | 次の確認 |
|---|---|
| クライアントからSYNが出ない | アプリが接続を試しているか、宛先・名前解決・端末側処理 |
| SYNは出るが応答がない | 宛先でSYNを観測できるか、往路と復路のFW・経路 |
| SYNにRSTが返る | 待ち受け、接続拒否、RSTを返した装置 |
| サーバーがSYN/ACKを繰り返す | クライアントへ届くか、最後のACKがサーバーへ届くか |
| 3段階は成立、その後に失敗 | TLS、認証、アプリケーション応答 |
RSTが返る場合は、無応答と違って拒否や中断の応答が見えています。サービスの待ち受けや端末の処理に加え、途中の装置がRSTを返していないかも候補になります。「RSTだから相手のサーバーが壊れた」とは限りません。
表に当てはめる前に、取得場所、時刻、フィルターも残します。キャプチャの取りこぼしで一部が見えないこともあるため、見えないパケットをそのまま通信上の欠落と決めず、別地点やログと照合します。
TCPがつながっても、Webの成功までは分からない
3回のやり取りが成立したら、TCP接続の開始は進んでいます。では、Webページも使えると言えるでしょうか。HTTPSでは、この先にTLSによる暗号化と相手確認、Webの要求と応答があります。
TLSで証明書の確認に失敗すれば、TCPがつながっても利用者にはエラーが出ます。Webサーバーが要求を受けても、アプリが処理を終えられなければ、ページの操作は成功しません。
つまり「TCP接続が成立」「TLSが完了」「目的の画面を使えた」は、進んだ段階が違う結果です。調査では、どこまで進んだかを先に書くと、その次の機能を担当する人へ渡せます。
逆に、TCPのSYNに返事がない段階で、Web画面の表示内容を調べても材料は増えにくいでしょう。ハンドシェイクを読めるようになると、ネットワークの接続開始と、その先のサービスを分けて考えられます。
接続開始からデータまで、続けて読む
ここまでを一本の接続で読み直します。PCのSYNが1000、サーバーのSYNが7000なら、最初のデータの位置はそれぞれ1001と7001です。開始手順の後にデータを見つけたら、今度は長さとAckの進み方を追います。
受信側がAckを進めたことは、その位置まで受信した範囲を読む手掛かりになります。ただし、アプリが注文やログインなどの処理を完了した意味ではありません。TCPの確認とアプリの結果は分けます。
動画を見るときも、SYNの名前だけを探すより、「どちらが開始したか」「相手は何番を次に欲しいと言ったか」を追うと、数字が動作につながります。最初は一接続だけで構いません。
通信できない場面でも同じ順です。開始要求、相手の応答、最後の確認、その先のデータへと読みます。暗記した3語を並べるだけでなく、止まった段階を説明できれば、次に調べる場所を選ぶための知識になります。
