ITの教科書検索

第4章 通信の制御|4-2|コース全体 19本中14本目

入門読了 約8分更新日 2026-09-27

TCPの3ウェイハンドシェイクと再送制御

TCPは、3ウェイハンドシェイクで準備を確かめてから送り、届かなければ再送します。SYN・SYN+ACK・ACKの意味と、シーケンス番号とACK番号が数えるものを、数値と図で説明します。

目次
  1. 確認しながら送り、届かなければ送り直す
  2. 3ウェイハンドシェイクの流れ
  3. なぜ2回のやりとりでは足りないのか
  4. シーケンス番号とACK番号が数えているもの
  5. 再送制御:ACKが返らないとどうなるか
  6. ウィンドウサイズ:1つずつ待たないしくみ
  7. 接続の終了はFINで行う
  8. 練習問題

TCPは「確認しながら送り、届かなければ送り直す」ことで、届いたか分かるようにしている

TCPは、受信確認(ACK)で到達を確かめ、届かなければ再送します。この仕組みがあるので、Webページやメールは途中が欠けずに届きます。UDPには、この仕組みがありません。

TCPは通信を始める前に、3回のやりとりでお互いの準備を確認します。これを3ウェイハンドシェイクと呼びます。データを送るときは、どこまで送ったかをシーケンス番号で管理します。

相手からのACKが一定時間内に返らなければ、TCPは同じデータを再送します。ハンドシェイク・シーケンス番号・再送の3つの仕組みで、データが届くか、届かなかったことを送信側が把握できるようにしています。再送の回数には上限があり、それでも届かなければ接続を失敗とします。

3ウェイハンドシェイクの流れ

TCPはデータを送る前に、SYN・SYN+ACK・ACKの3回のやりとりで接続を確立します。このとき、お互いがどの番号からデータを数え始めるかも伝え合います。この番号を開始番号と呼びます。

クライアントサーバ① SYN送信seq=1000② SYN+ACKで応答seq=4000 ack=1001③ ACKで確認ack=4001
クライアントは、SYNで自分の開始番号 seq=1000 を伝えます。サーバはSYN+ACKを返し、受信の確認 ack=1001 と自分の開始番号 seq=4000 を同時に伝えます。クライアントは、ack=4001 のACKで、サーバの開始番号を受け取ったことを伝えます。双方の開始番号を確認できた時点で、接続が確立します。

開始番号は本来ランダムな32ビットの値ですが、ここでは説明のために、クライアント側を1000、サーバ側を4000とします。

やりとり向きseqack
① SYNクライアント → サーバ1000―
② SYN+ACKサーバ → クライアント40001001
③ ACKクライアント → サーバ10014001

①で、クライアントは自分の開始番号をseq=1000として伝えます。②で、サーバは自分の開始番号をseq=4000として伝えます。同時に、クライアントの開始番号を受け取ったことをack=1001で確認します。

③で、クライアントは、サーバの開始番号を受け取ったことをack=4001で確認します。これで双方が相手の開始番号を確認できたので、データの送信を始められます。

①と②では、1つのセグメント(TCPの送信単位)に載せられるデータの上限も相手に知らせます。この上限の値は、MTUとMSSの記事で説明しています。

なぜSYN→ACKの2回のやりとりでは足りないのか

TCPの通信では、クライアントからサーバへも、サーバからクライアントへもデータが流れます。そのため、クライアントとサーバがそれぞれ自分の開始番号を持ち、どちらの開始番号も相手に確認してもらう必要があります。

もし①SYN、②ACKの2回だけで終わらせると、①で伝えたクライアントの開始番号は確認できます。サーバも、②のACKで自分の開始番号を伝えることはできます。しかし、クライアントがそれを受け取ったことを、サーバは確認できません。

この最後の確認を行うのが、③のACKです。だから、2回ではなく3回のやりとりが必要になります。時間にすると、SYNとSYN+ACKで1往復、ACKでさらに片道分の、1往復半かかります。

ただし、③のACKにはデータを一緒に載せられるので、データを送り始められるのは1往復後からです。

HTTP/3が使うQUICはTCPを使わず、接続の準備と暗号の準備を1往復にまとめます。TCPとの往復の差は、HTTP/3とQUICの記事の図で比べられます。

サーバは、①を受けると、③が届くまで接続の情報を保持します。この性質を悪用し、③を返さないSYNを大量に送って受付の枠を使い切らせる攻撃が、SYNフラッドです。

シーケンス番号とACK番号が数えているもの

シーケンス番号とACK番号は、パケットの個数ではなくバイト数を数えています。表では、シーケンス番号をseq、ACK番号をackと書いています。

SYNとFINは中身のデータを持ちませんが、それぞれ1バイト分の番号を消費する決まりです。ハンドシェイクのack番号が「相手のseq + 1」になっているのは、このためです。

データを送るときも同じです。たとえばハンドシェイクの後、クライアントが200バイトのデータをseq=1001から送ると、サーバはack=1201を返します。これは「1001番目から1200番目までの200バイトを受け取った。次は1201番目を待っている」という意味です。

このようにACK番号は、次に受け取りたいバイトの番号であり、それより前のバイトがすべて届いたことも表します。この確認のしかたを累積の確認応答と呼びます。

再送制御:ACKが返らないとどうなるか

TCPの再送は、書留郵便の受領印に近い考え方です。送った側は、受領印が返ってくるまで、本当に届いたかどうかを確認できません。TCPでは、ACKがこの受領印にあたります。

そこでTCPは、データを送るたびにタイマーを開始します。一定時間内にACKが返らなければ、そのデータは失われたとみなし、同じデータを再送します。データが途中で失われることをロストと呼びます。

クライアントサーバ① データ送信seq=1001(200バイト)消失② タイムアウトACK待ち・応答なし③ 再送seq=1001(同じデータ)④ ACKで確認ack=1201
クライアントが送ったseq=1001からの200バイトのデータが、途中で失われてサーバに届かなかった例です。ACKが返らないままタイムアウトになると、クライアントは同じデータを再送します。今度はサーバに届き、ack=1201が返ります。

再送してもACKが返らなければ、さらに時間をおいて再送を繰り返します。ただし、再送の回数には上限があり、それでも届かなければ接続を失敗とします。

つまりTCPは、データが届くか、届かなかったことを送信側が把握できる仕組みで、必ず届くわけではありません。

ウィンドウサイズ:1つずつ待たないしくみ

ここまでの説明では、1つ送るたびにACKを待っていました。しかし、これでは往復にかかる時間の分だけ、通信全体が遅くなってしまいます。

そこでTCPは、ACKを待たずに、まとめて送ってよいデータ量を決めておきます。その範囲内なら、次々とデータを送り出せます。

まとめて送れる量を決める仕組みは2つあります。1つは、受信側が、自分が処理できる量をTCPヘッダのウィンドウサイズ欄で伝える仕組みで、フロー制御と呼びます。フロー制御という考え方自体は、データリンク層の通信手順にもあります。その手順は、伝送制御の記事で説明しています。

もう1つは、送信側が回線の混み具合を見て、送る量を調整する仕組みで、輻輳(ふくそう)制御と呼びます。輻輳制御では、少ない量から始めて、ACKが返るたびに送信量を増やしていきます。

実際に送ってよい量は、この2つのうち小さい方に制限されます。

接続の終了はFINで行う

接続を終えるときは、SYNの代わりにFINという制御フラグを使います。FINもSYNと同じくシーケンス番号を1つ消費するので、相手からのACKで確認されます。

データは双方向に流れているので、それぞれの方向で終わりを伝える必要があります。「もう送るデータはない」という意思表示がFINで、それに対する確認がACKです。両方向でFINとACKを交わすので、合計4回のやりとりで接続を閉じます。この閉じ方を4ウェイクローズと呼びます。

TCPヘッダには、どのアプリ宛てかを示す番号も入っています。それがポート番号です。

3回のやりとりが実際にどう見えるかは、Wiresharkの記事の疑似パケット一覧で確認できます。

練習問題(全5問)

Q1クライアントがseq=2000のSYNを送ったとき、サーバが返すSYN+ACKのack番号は?
Q2なぜSYN→ACKの2回のやりとりだけでは接続を確立できないのか?
Q3送信したデータのACKが一定時間内に返ってこなかった場合、送信側はどうする?
Q4ウィンドウサイズの役割として正しいものは?
Q5TCP接続を終了するときに使われる、SYNとは別の制御フラグは?

選んでから「採点する」を押すと、解説つきで答え合わせができます。

おすすめの本 PR

この記事の内容を扱っている本です。

目的別の本の選び方を見る

入門コースを読み進める

入門コース 全19本中14本目