シーケンス番号が手掛かり?TCPの「順序制御」とは?

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

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

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

プロフィール

[/voice]

こんにちは、Tomです。

今回は、

「TCPにおける順序制御」

についてお話していきます。

1.はじめに

1-1.順序制御とは?

TCPにおける順序制御とは、

「分割されて送られてきたデータを、正しい順番に並べて復元する制御」

のことです。

 

ネットワークでは、一度に送受信できるデータサイズが決まっています。

例えば、イーサネットとTCP/IPで構築されたネットワークなら、一度に送受信できるアプリケーションメッセージの最大値は1460バイトです。この最大値をMSS(Maximum Segment Size)と言います。

MSSについては、以下の記事で詳しく説明していますので、そちらをご覧ください。

“なんとなくわかる”では困る!MTUとMSSの違いとは?

 

アプリケーションメッセージとは、Webページやメールなどの各アプリケーションが処理するデータのことです。

例えば、メールの添付ファイルのサイズが大きい場合、MSSを簡単に超えてしまいます。

そのとき、TCPではメッセージを分割して送信します。

この分割したメッセージを送信したときに、受信したホストが元のデータに復元できるようにするための仕組みが「順序制御」です。

1-2.順序を把握する方法

では、どうやってバラバラに分割されたデータを元のデータに復元するのでしょうか?

 

答えは、

「シーケンス番号」

というものを使ってデータにマーキングをするのです。

下の図は、TCPヘッダの中身です。

このTCPヘッダの中には、赤枠で囲った「シーケンス番号」という領域があります。

TCPで分割したデータを送信する場合、分割されたデータの一つ一つに、この「シーケンス番号」を付与して送信します。

分割されたデータを受信したホストは、シーケンス番号を見てデータを並び替え、元のデータに復元するのです。

2.順序制御の流れ

それでは、実際にシーケンス番号を付与してデータを送信する流れを見ていきましょう。

 

まず、TCPの場合は通信を行うホストの間でコネクションを確立します。

今、3ウェイハンドシェイクを経て2台のホストの間にコネクションが確立されているとします。

3ウェイハンドシェイクについては、下の記事をご覧ください。

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

 

この状態で、ホストAから合計3000バイトのデータが送信されるとします。
なお、ここではMSSを1000バイトとします。

まず、ホストAから1000バイトのデータを送ります。

このとき、「シーケンス番号」と「確認応答番号」は、3ウェイハンドシェイクでコネクションを確立した時の値が入ります。
ここでは、両方「100」とします。

 

ホストAから一つ目のデータを受け取ったホストBは、データを受け取ったことを知らせるために、「確認応答」を送信します。

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

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

この「確認応答番号」で、次に受信したいシーケンス番号をホストAに通知します。

 

次に、ホストAからまた1000バイトのデータを送ります。

このとき、「シーケンス番号」は、「ホストBから送られてきたセグメントの確認応答番号」が入ります。
ホストBから、言われたとおり「シーケンス番号」を「1100」にしてデータを送るのです。

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

「確認応答」はTCPヘッダしか送らないので、データサイズは「0」なのです

 

ホストAから二つ目のデータを受け取ったホストBは、データを受け取ったことを知らせるために、「確認応答」を送信します。

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

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

また「確認応答番号」で、次に受信したいシーケンス番号をホストAに通知します。

 

最後に、ホストAから1000バイトのデータを送ります。

「シーケンス番号」は、「ホストBから送られてきたセグメントの確認応答番号」が入ります。
先ほどと同じように、ホストBから、言われたとおり「シーケンス番号」を「2100」にしてデータを送ります。

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

 

ホストAから三つ目のデータを受け取ったホストBは、データを受け取ったことを知らせるために、「確認応答」を送信します。

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

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

また「確認応答番号」で、次に受信したいシーケンス番号をホストAに通知します。

 

しかし、もうデータはないので、ホストAはデータを送りません。

この後の流れは、別の分割されたデータがあれば、同じような手順で送信します。
もう送信すべきデータがなければ、コネクションの切断に移行します。

コネクションの切断手順に関しては、先ほどご紹介した記事をご覧ください。

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

 

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

この流れで分割されたデータを受け取ったホストBは、下の図のようにシーケンス番号順にデータを並び替えて元のデータに復元します。

仮に、先ほどの流れのような順番でデータが送られてこなくても、シーケンス番号を見ることで、元どおりに復元することができます。

3.まとめ

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

TCPには今回お話した「順序制御」の他にさまざまな制御があります。

そちらに関しても記事を書いたので、併せてご覧ください。

再配達します!TCPの「再送制御」とは? 一気に送っていいよ!TCPの「ウィンドウ制御」とは?

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