TCPの信頼性制御 — 落としても、必ず届ける
インターネットの回線は、荷物を落とすことがある運送業者のようなものです。ケーブルの途中の機器が混み合えば、パケットは黙って捨てられます。それでもファイルが壊れずに届くのは、TCPが「落ちたことに気づいて、積み直す」仕組みを持っているからです。
そのために TCP が使う道具は2つだけ。受け取ったよという返事(ACK)と、返事が来ないときのタイムアウトです。そしてもう一つ、一度に何台のトラックを出すかを自分で加減します。下の図1で荷物を落としながら、TCPがどう立て直すかを見てください。
落としたことに、どうやって気づくのか
TCPは荷物1つひとつに通し番号(シーケンス番号)を貼ります。受信側は受け取った番号をACKという返事で送り返す。送信側は「3番のACKだけ来ない」と分かるので、3番だけ積み直せば済むわけです。
ではACKが返らないときは? TCPは荷物を出した瞬間にストップウォッチ(再送タイマー)を回し始めます。往復にかかる時間を普段から測っておき、それを基準にした制限時間を過ぎてもACKが来なければ、落ちたとみなして同じ荷物をもう一度送る。これが再送です。図1でロス率を上げると、赤く落ちた番号が次のラウンドでもう一度出てくるのが分かります。
つまり TCP は「落ちない回線」を用意しているわけではありません。落ちる前提で、落ちたら気づいて出し直す。この一往復の約束だけで、信頼できない回線の上に信頼できる通信を作っているのです。
一度に何台出すか — 輻輳ウィンドウ
1台ずつ送ってACKを待っていては遅すぎます。かといって一度に大量に流し込めば、途中の機器があふれてもっと落ちる。そこで TCP はいま何台まで同時に出していいかを自分で決めます。これが輻輳ウィンドウ(cwnd)です。
増やし方は臆病で、減らし方は大胆です。全部無事に届いたら台数を倍にしていき(スロースタート)、しきい値を超えたら1台ずつ慎重に増やす。そして1台でも落ちた瞬間に、一気に1台まで引き戻す。図1のグラフに現れるノコギリの歯のような形が、その正体です。TCPは「行けるところまで攻めて、ぶつかったら下がる」を延々と繰り返しながら、回線がちょうど耐えられる速度を探り続けています。
- シーケンス番号
- 荷物に貼る通し番号。抜けや順番の入れ替わりを受信側が検出・整列できる。
- ACK
- 「ここまで受け取った」という返事。これが来ない番号だけを送り直せばよい。
- 再送タイムアウト(RTO)
- ACKを待つ制限時間。実測した往復時間をもとに自動で調整される。
- 輻輳ウィンドウ(cwnd)
- ACKを待たずに同時に送ってよい量。回線の混み具合に応じて増減する。
- スロースタート
- 1から始めて倍々に増やす立ち上げ方。名前に反して増え方は速い。
まとめ
TCPの信頼性は、番号を貼る・返事を待つ・来なければ出し直すという素朴な3手で成り立っています。そこに「落ちたら送る量を減らす」という譲り合いを重ねることで、誰も全体を指揮していないインターネットが、それでも詰まらずに動いている。ロスは異常ではなく、TCPにとっては速度を調整するための合図――そう捉えると、通信が遅い場面で何が起きているのかが見えやすくなります。