コンピュータが握手?3ウェイハンドシェイクとは?

[voice icon=”https://tomslifestylelab.com/wp-content/uploads/2019/05/tom0212.png” name=”この記事を書いている人” type=”l”]

ネットワークエンジニア
Tom

Tomとかいうやつが何者なのか知りたい方は下のプロフィールをご覧ください。

プロフィール

[/voice]

こんにちは、Tomです。

今回は、

「3ウェイハンドシェイク」

について解説していきます。

 

「3ウェイハンドシェイク」という言葉を聞いたことはありますか?

 

TCPの勉強していると、参考書などにこの言葉が出てくることがあります。

しかし、この言葉を覚えているだけで、実際はどのようなものなのか理解していない、という方もいるのではないでしょうか?

 

今回は、聞いたことあるけどよくわかっていない「3ウェイハンドシェイク」について、解説していきます。

1.3ウェイハンドシェイクとは?

「3ウェイハンドシェイク」とは、TCPにおいて、通信相手のホストとのコネクションを確立するときの手順のことです。

名前の通り、コネクションを確立する時のやり取りが「3回の手順を経て握手している」ように見えます。

 

3回の手順を経て握手をするとは、人間で言えば次のようなやり取りです。

A「握手していい?」

B「いいよ。僕も握手していい?」

A「じゃあ握手しよう。」

といった感じです。少し奇妙ですね。

特にBくんの「僕も握手していい?」ってなんでしょうか。
「僕も」ってそりゃ握手なんだからそうでしょって感じですよね。

 

しかし、コンピュータは人間とは違うので、この奇妙な手順じゃないと握手(コネクションを確立)できません。

TCP通信を行うコンピュータでは、この方法で相手とのコネクションを確立します。

 

ちなみに、データ送信とコネクションの切断は、「3ウェイ」ではないのですが、同じような手順なので一緒に覚えてしまいましょう。

それでは、「コネクションの確立、データ送信、コネクションの切断」の一連の流れをみていきましょう。

2.コネクションの確立

まずは、コネクションの確立からです。

ホストAとホストBがTCPによってデータ転送を行う場合を考えてみましょう。

このとき、セグメント内のTCPヘッダの「シーケンス番号」、「確認応答番号」、制御ビットの各ビット「SYN」、「ACK」、「FIN」がどのような値になるのかも見ていきます。

 

下の図のように、まずホストAがホストBに対して、「コネクション確立要求」を送信します。

先ほどの人間の例で言えば、Aくんの「握手していい?(確立要求)」にあたります。

このとき、ホストAからのセグメントでは、「シーケンス番号」はランダムな値をとり、「確認応答番号」は「0」が入ります。

制御ビットは、確立要求なので、「SYN」のみ「1」となります。

 

ホストAからの確立要求を受け取ったホストBは、「ホストAからの確立要求に対する確認応答」と「コネクション確立要求」を返します。

先ほどの人間の例で言えば、Bくんの「いいよ(確認応答)。僕も握手していい?(確立要求)」にあたります。

このとき、ホストBからのセグメントでは、「シーケンス番号」はランダムな値をとります。

そして、「確認応答番号」は、「ホストAから送られてきたセグメントのシーケンス番号」に1をプラスした値が入ります。

制御ビットは、確認応答なので「ACK」に「1」が入り、確立要求なので「SYN」に「1」が入ります。

 

最後にホストAから、「ホストBの確立要求に対する確認応答」が送信されます。

先ほどの人間の例で言えば、「じゃあ握手しよう(確認応答)。」にあたります。

このとき、「シーケンス番号」には、最初のホストAから確立要求で使ったシーケンス番号に1をプラスした値が入ります。

そして、「確認応答番号」には、「ホストBから送られてきたセグメントのシーケンス番号」に1をプラスした値が入ります。

制御ビットは、確認応答なので「ACK」に「1」が入ります。

 

最後の一連の流れをまとめて見てみましょう。

この3回の手順を経て、ホストAとホストBの間でコネクションが2つ確立します。
上りと下りの2つです。

コネクションが確立したら、実際にデータを送信することが可能になります。

3.データ転送

次に、先ほど確立したコネクション上で実際にデータを送信する場合を見ていきましょう。

 

例えば、下の図のようにホストAからデータサイズが1000バイトのデータを送信するとします。

このとき、初めてデータの送信を行うので、「シーケンス番号」、「確認応答番号」は、コネクションの確立時に用いた値を使用します。

制御ビットは、「ACK」のみ「1」となります。

 

次に、ホストBからもデータ(データサイズ=500バイト)が送信されたとします。

このときに使うコネクションは、先ほどとは違うコネクションです。

このとき、「シーケンス番号」は、「ホストAから送られてきたセグメントの確認応答番号」が入ります。

「確認応答番号」は、「ホストAから送られてきたセグメントのシーケンス番号」+「受信したデータサイズ(バイト)」の値が入ります。ここで言えば、「101+1000=1101」となります。

制御ビットは、「ACK」に「1」が入ります。

 

さらにホストAからデータが送信されたとします。

このとき、「シーケンス番号」は「ホストBから送られてきたセグメントの確認応答番号」が入ります。

「確認応答番号」は、「ホストBから送られてきたセグメントのシーケンス番号」+「受信したデータサイズ(バイト)」の値が入ります。ここで言えば、「201+500=701」となります。

制御ビットは、「ACK」に「1」が入ります。

 

最後にまとめて見てみましょう。

データ送信は、このような手順で行われます。

3.コネクションの切断

それでは最後に、「コネクションの切断」の流れを見ていきましょう。

コネクションの切断も、人間の場合に例えてみると次のようになります。

A「手を離すね。」

B「いいよ。」

B「僕も手を離すね。」

A「じゃあ手を離そう。」

といった感じです。

実際にコンピュータの動作を見てみましょう

 

データ送信が完了したら、ホストAは「コネクションの切断通知」をホストBに対して送信します。

先ほどの人間の例で言えば、Aくんの「手を離すね(切断通知)」にあたります。

このとき、「シーケンス番号」は、「先ほど自分がデータ送信を行なった際のシーケンス番号」+「送信データサイズ」の値が入ります。

「確認応答番号」は、データ送信を行なった際のものと同じ値が入ります。

制御ビットは、「ACK」に加えて「FIN」にも「1」が入ります。

 

ホストAからの切断通知を受け取ったホストBは、それに対する確認応答を送信します。

先ほどの人間の例で言えば、Bくんの「いいよ(確認応答)。」にあたります。

このとき、「シーケンス番号」は「ホストAから送られてきたセグメントの確認応答番号」が入ります。

「確認応答番号」には、「ホストAから送られてきたセグメントのシーケンス番号」に1をプラスした値が入ります。

また、制御ビットは、「ACK」に「1」が入ります。

 

それと同時に、今度はホストBからホストAに対して「コネクションの切断通知」が送信されます。

先ほどの人間の例で言えば、Bくんの「僕も手を離すね(切断通知)。」にあたります。

このとき、「シーケンス番号」と「確認応答番号」には、先ほどと同じ値が入ります。

また、切断通知なので、制御ビットは、「ACK」に加えて「FIN」にも「1」が入ります。

 

そして最後に、ホストAからホストBに対して、切断通知に対する確認応答を送信します。

先ほどの人間の例で言えば、Aくんの「じゃあ手を離そう(確認応答)。」にあたります。

このとき、「シーケンス番号」は「ホストBから送られてきたセグメントの確認応答番号」が入ります。

「確認応答番号」には、「ホストBから送られてきたセグメントのシーケンス番号」に1をプラスした値が入ります。

また、制御ビットは、「ACK」に「1」が入ります。

 

最後にまとめて見てみましょう。

このような流れで、コネクションの切断を行い、通信を終了します。

4.まとめ

いかがでしたでしょうか?

3ウェイハンドシェイクは一見難しそうに感じますが、一つずつ順を追って見ていけば、ちゃんと理解することができます。

また、3ウェイハンドシェイクでの「シーケンス番号」や「確認応答番号」、「制御ビット」の値の変化を理解すれば、TCPにおけるその他の制御についても、理解しやすくなります。

ぜひ何度ども読んであなたの知識にしてください。

 

それでは、最後まで読んでくださり本当にありがとうございました。