TCPの制御(スライディングウィンドウ)

 TCPにおける通信では、ACK(確認応答)を受け取るまでに送出できるデータの範囲であるウィンドウを徐々にスライドさせながら通信を行います。この方式ことを「スラインディングウィンドウ」と呼びます。

文章だけでは、なかなか理解しにくいので下図を使って解説します。

説明

まず、図に使っている記号の説明です。

SEND(x):セグメントの送信。Xは、シーケンス番号。
ACK(y,z):確認応答。yはACK番号、zはウィンドウサイズ。

TCP通信に先立ち、「ウィンドウサイズ=3000」、「MSS=1000」でコネクションを確立しています。

①送信側
・SEND(1),SEND(1001),SEND(2001)の送信
「ウィンドウサイズ=3000」なので、一度に3つのセグメントを送信します。

②受信側
・SEND(1)の受信
セグメント1(1~1000)を受信します。「ウィンドウサイズ=2000」になります。

・ACK(1001,2000)の送信
空バッファサイズは、2000バイトです。「ACK=1001」、「ウィンドウサイズ=2000」で応答します。

③受信側
・SEND(1001)の受信
セグメント2(1001~2000)を受信します。「ウィンドウサイズ=1000」になります。

・ACK(2001,1000)の送信
空バッファサイズは、1000バイトです。「ACK=2001」、「ウィンドウサイズ=1000」で応答します。

④受信側
・バッファ内のセグメント1(1~1000)、セグメント2(1001~2000)の処理が完了します。
バッファ内のセグメントの処理が完了したので、「ウィンドウサイズ=3000」になります。

⑤受信側
・SEND(2001)の受信
セグメント3(2001~3000)を受信します。「ウィンドウサイズ=2000」になります。

・ACK(3001,2000)の送信
空バッファサイズは、2000バイトです。「ACK=3001」、「ウィンドウサイズ=2000」で応答します。

⑥送信側
・ACK(1001,2000)の受信
 「ウィンドウサイズ=2000」です。セグメント1(1~1000)は、「ACK=1001」より無事に届いていることが分かります。セグメント1を再送する必要がないので、「ウィンドウ=2000」に変更します。セグメント2(1001~2000)、セグメント3(2001~3000)は、既に送信済みで、送信できるセグメントがないので送信しません。

⑦送信側
・ACK(2001,1000)の受信
 「ウィンドウサイズ=1000」です。セグメント2(1001~2000)は、「ACK=2001」より無事に届いていることが分かります。「ウィンドウ=1000」に変更し、ウィンドウを右に1スライドさせます。

 ウィンドウ内にあるセグメント3(2001~3000)は、既に送信済みですが、確認応答をまだ受信していません。送信できるセグメントがないので送信しません。

⑧送信側
・ACK(3001,2000)の受信
 「ウィンドウサイズ=2000」です。セグメント3(2001~3000)は、「ACK=3001」より無事に届いていることが分かります。「ウィンドウ=2000」に変更し、ウィンドウを右に2スライドさせます。
・SEND(3001),SEND(4001)の送信
 ウィンドウ内に入ったセグメント4(3001~4000)、セグメント5(4001~5000)は、まだ送信していません。そこで、セグメント4とセグメント5を送信します。

⑨受信側
・バッファ内のセグメント3(2001~3000)の処理が完了します。
バッファ内のセグメントの処理が完了したので、「ウィンドウサイズ=3000」になります。

⑩受信側
・SEND(3001)の受信
セグメント4(3001~4000)を受信します。「ウィンドウサイズ=2000」になります。
・ACK(4001,2000)の送信
空バッファサイズは、2000バイトです。「ACK=4001」、「ウィンドウサイズ=2000」で応答します。

⑪受信側
・SEND(4001)の受信
セグメント5(4001~5000)を受信します。「ウィンドウサイズ=1000」になります。
・ACK(5001,1000)の送信
空バッファサイズは、1000バイトです。「ACK=5001」、「ウィンドウサイズ=1000」で応答します。

⑫送信側
・ACK(4001,2000)の受信
 「ウィンドウサイズ=2000」です。セグメント4(3001~4000)は、「ACK=4001」より無事に届いていることが分かります。「ウィンドウ=2000」に変更し、ウィンドウを右に1スライドさせます。
・SEND(5001)の送信
 ウィンドウ内のセグメント5(4001~5000)は、既に送信済みです。セグメント6(5001~6000)は、まだ送信していません。そこで、セグメント6を送信します。

まとめ

 このように、ウィンドウサイズの増減は、受信側が送信側へACKセグメントを使って返すことで通知します。そうすることで、ウィンドウサイズを動的に変化させることができます。

 この様子は、シーケンス番号上で、まるで、ウィンドウがスライドしたかのように見えるため、スライディングウィンドウと呼ばれています。ウィンドウは、今送信中のデータだけが見える窓ということになります。