Lesson3まででTCPの基本は理解できただろう。ただしTCPの世界は奥が深い。効率よくデータを転送するために,さまざまな工夫が加えられている。その一端を覗いてみよう。ここでは,受信できる量を通知することでデータを効率よく送れるようにするフロー制御と,再送の効率を上げる工夫を紹介する。

受信側から転送ペースを調節する

 まずはフロー制御から。TCPでは,データを載せたTCPパケットを連続して転送できる。ただし,際限なく連続して転送するとちょっと困ったことが起こる(図4-1)。

図4-1●受信できる量を通知することで転送効率を上げる
図4-1●受信できる量を通知することで転送効率を上げる
TCPでは連続受信できるデータ量をウインドウ・サイズとして連絡し合う。的確に連続転送することで転送時間を短くできる。こうした処理を「フロー制御」と呼ぶ。 [画像のクリックで拡大表示]

 TCPスタックは,受け取ったデータをいったん受信バッファに溜めて届け先となるアプリケーションに引き取ってもらう。際限なくデータが転送されてくると,受信バッファからデータがあふれてしまう。

 そこでTCPでは,連続して受信できるデータ量を「ウインドウ・サイズ」というバイト単位の値でお互いに通知し合うことになっている。一挙に大量のデータが届いたり,送信先のアプリケーションが受信バッファからデータを引き取るのが遅れると,受信バッファの空きが小さくなる。通知するウインドウ・サイズを空きに応じて変更することで,データを受信しきれなくなることを防ぐわけだ。

受信側から再送を要求する

 効率を上げる工夫はほかにもある。TCPの元々の標準として決められた方法ではないが,データが届かなかったときに受信側が再送を要求できるようになっているのもその一つである。

 Lesson3で見たようにTCPの再送の基本は,送信側が一定時間内に確認応答を受け取れなかったときにデータを送り直すというものだ。ただ,これでは時間切れを待たないとデータが再送できない。データの抜けに気付いた受信側が積極的に再送を要求できれば,転送効率は向上する。

 そこで登場したのが再送の二つの工夫だ(図4-2)。

図4-2●再送の効率を上げる二つの工夫がある
図4-2●再送の効率を上げる二つの工夫がある
時間切れを待ってすべてのデータを再送するのは効率が悪い。そこでTCPは,受信側から再送を要求したり,受信側が抜けたデータを送信元に通知するしくみを用意している。 [画像のクリックで拡大表示]

 順番に見ていこう。まずは「高速再転送」からだ(図4-2の工夫1)。パケットの抜けに気付いた受信側が,抜けたデータの前のパケットの確認応答を,正規のものを含め合計3回以上連続して送る。送信側が確認応答を連続して受信したら,再送要求だと判断して,ただちにパケットを再送する。

 TCPスタックが高速再転送で再送を要求したときに,万一相手が高速再転送に対応していなくいと,相手はわからずに時間切れを待って再送する。効率は上がらないが不具合も起こらない。

 高速再転送は,TCPの機能強化の位置付けだ。今ではほとんどのTCPスタックで使える。

 もう一つのSACK(サック)は,途中のパケットが抜けている場合,受信側が送信側に抜けたパケットを通知する方法だ(同工夫2)。飛び飛びに受信したデータを通知することによって,抜けているデータがわかるようになっている。送信側はその内容を見て,抜けている部分だけを送り直す。SACKと高速再転送を併用すれば,受信側が抜けたデータだけ直ちに再送してもらえる。

 SACKを使用するときは,TCPコネクションの確立時に双方のTCPスタックの間でSACKを使うかどうかをあらかじめ確認しておく。受信したデータを正確を伝える情報は,TCPヘッダーのオプション部分に書き込む。

 SACKはすべてのTCPスタックで使えるわけではない。ただし,Windows 2000以降のWindowsで使えるなど,一般化しつつある。