iPhoneからC言語を使ってTCP通信してみる、その2「3ウェイハンドシェイクを理解する」

www.101010.fun

前回は、TCPの流れを大雑把に掴んだので、今回はコネクションの確立、「3ウェイハンドウェイク」について理解を深めていこうと思う。

3ウェイハンドシェイク

f:id:araemonz:20181129151547j:plain

3ウェイハンドシェイクを理解するにあたって、TCPパケットで意識する部分はたったの4つで良い。

f:id:araemonz:20181129153228j:plain

また、次のようなルールがあることを先に覚えておくと理解しやすい。

シーケンスACK番号のルール

「相手から受信したシーケンス番号」+「データサイズの値」

ただし、3ウェイハンドシェイクでは「相手から受信したシーケンス番号」に「1」を加算した値となる

それでは図のやり取りを見ていこう。

最初に、クライアントがサーバーに対してSYNパケットを送る。SYNパケットといってもSYNフラグを1、ACKフラグを0にしただけだ。シーケンス番号は最初だけはランダムな値ということなので、ここでは仮に1000としよう。

f:id:araemonz:20181129153756j:plain

次に、 SYNパケットを受け取ったサーバーは、クライアントへSYN ACKパケットを返す。この時のシーケンスACK番号は「シーケンスACK番号のルール」に従えば、受信したシーケンス番号の1000に1を加えた1001の値になる。

サーバー側のシーケンス番号は最初の送信だけはランダム値なので、仮に9000とする。

f:id:araemonz:20181129153800j:plain

最後に、SYN ACK パケットを受けとったクライアントは、接続開始のACKパケットを送る。シーケンス番号は相手から受け取ったシーケンスACK番号になるという決まりがあるので、そのまま1001となる。また、シーケンスACK番号は先ほどと同様に、送られてきたシーケンス番号9000に1を足して9001となる。

f:id:araemonz:20181129153803j:plain

以上のようにシーケンス番号とACK番号が加算されながら入れ替わる。そのことで、通信の状態をお互いに、把握できるようになっているわけだ。言い換えれば、どこまで受信、送信できているかということを、このシーケンス番号とシーケンスACK番号を見れば確認できる。まさにシーケンス、「順番に並んでいる」ことを意識した通信だ。

f:id:araemonz:20181129151547j:plain

参考:

TCP/IP - TCP 3ウェイハンドシェイク

↑非常に分かりやすかったです。

3ウェイ・ハンドシェイク - Wikipedia