TCP における確認応答と再送制御

広告

広告

TCP の透過性

最終更新
2004-12-26T00:00:00+09:00
この記事のURI参照
https://www.7key.jp/nw/tcpip/tcp/tcp2.html#transp

TCPトランスポート層としての役割として大切なのは通信の信頼性を確保することです。今回はコネクションの中で、その信頼性を確保するためのかなめとなる部分について説明を行います。このかなめとなる機能は大きく分けて確認応答再送制御の二つから成り立ちます。確認応答は「データをここまで受け取りましたよ」とあいづちをうつ機能のことを言い、再送制御は相手にデータが届かなかったことを検知し、速やかに届かなかったデータを相手に再送する機能のことを言います。これらの機能により、ローカルのアプリケーション通しが通信しているのと変わらない環境をネットワーク経由でも実現することができるのです。こうしたコネクションの性質のことを「透過性」と呼んでいます。では、順番にみていきましょう。

確認応答

最終更新
2004-12-26T00:00:00+09:00
この記事のURI参照
https://www.7key.jp/nw/tcpip/tcp/tcp2.html#kak

確認応答のために重要な役割を果たすのが、シーケンス番号確認応答番号ACK番号とも呼ばれます)です。スリーウェイハンドシェイクでも少し説明しましたが、ここでじっくりと説明しましょう。コネクションとスリーウェイハンドシェイクの話は分かっているものとして話を進めますので、不安な方は復習に戻って下さい。

コネクションを確立する際にスリーウェイハンドシェイクで必要な情報の交換を行いました。その中の一つにMSS【Maximum Segment Size】というものがあります。TCP とはにて少し触れましたが、TCP はデータの容量が大きい場合セグメントという単位にデータを分割します。その分割する基準となるのが MSS なのです。専用のフィールドは無いのですが、接続元端末が最初に送る SYNパケットのオプション欄に接続元端末の MSS が記述されます。それを受け取った接続先端末は、その値を超えず自分が転送可能な MSS を同じくオプション欄に記述し、ACK+SYN パケットを送信します(Figure:TCP2-0)。

TCP2-01

これによりお互いが処理できる最大値が分かるので、この MSS を元にデータを分割しセグメントを作ります。

また、確認応答の為に重要な役割を果たすのがシーケンス番号です。シーケンス番号はセグメントの順番を管理をしたり、セグメントに抜けが無いかをチェックしたりするのに使うものです。ただ、実はこの番号、連番になっているわけではありませんし、「0」や「1」から始まるわけでもありません。純粋に「1、2、3…」となっていれば話は簡単なのですが、そんなに単純なものではないのです。ある決められた数値から毎回シーケンス番号を始めると、セグメントの偽造が行いやすくなります。結果、通信妨害やコネクションの乗っ取りなどを行われる原因となりますので、スリーウェイハンドシェイクの際にランダムに決めた値を初期値とするのです。TCP ヘッダ(TCP とはを参照)を見てもらえば分かると思いますが、32オクテット(0〜42億9496万7296)の中から任意の値が交換されると言うわけです(Figure:TCP2-01)。そして初期値以降は送信するデータの先頭からのオクテット数でセグメントを管理しています。どういうことか実際に下図(Figure:TCP2-02)を見てください。

TCP2-02

データを受け取った際の応答確認パケット(ACK パケット)内の応答確認番号(ACK 番号)は

シーケンス番号+受信したデータサイズ

となっています。即ち、「次受信するセグメントシーケンス番号をあらかじめ送信元に通知している」こととなります。ただ、「受け取りました」と返事をするのではなく、「このデータまでは受け取りましたので次はここからお願いします」と返事をすることにより、セグメントに抜けの無い通信ができることとなります。また上図(Figure:TCP2-02)を見て気づかれた人もいるとは思いますが、データを2回連続して送る処理を行っていますよね。1つのセグメントを受信するたびに ACK パケットを1つ返すのは、確実ではありますがとても効率が悪いのです。TCP では、別途説明しますウィンドウサイズ受信バッファの大きさ)以内であれば、ACK パケットを待たずに次のセグメントを送信しても良いことになっています。受信側もまとめて受信したセグメントに対して1つのACK パケットを返せば良いので幾分か効率が上がるのです。

再送制御

最終更新
2004-12-26T00:00:00+09:00
この記事のURI参照
https://www.7key.jp/nw/tcpip/tcp/tcp2.html#sas

再送タイムアウト

確認応答の手順は上記の通りですが、ここでもし送信したセグメントに対する ACK パケットが返ってこなければどうするのでしょう。TCP では何らかの原因で一定時間の間 ACK パケットの応答が無い場合、応答が無かったセグメントを再送します。この再送するまでの待ち時間のことをRTO【Retransmission Time Out】(再送タイムアウト)と呼びます。RTO の初期値はRTT【Round Trip Time】と呼ばれる「パケットが相手まで往復する時間」の「4倍+α」となっています。そして、再送が繰り返される場合は、途中経路が混雑しているなどの原因が考えられるため、RTO の値は再送を行うたびに2倍に増やされ、最大で 64 秒までなります。更に、RTT は初期値を3秒とし、これまでに送ったデータに対し確認応答が返って来るまでにかかった時間から算出します。統計上、経路が正常であればほとんどの場合この時間以内に ACK パケットが戻ってくることになっているようです。

TCP2-03

高速再転送

ただ、再送制御ではパケットが欠落するたびに再送タイムアウトを待つので効率的ではありません。TCP には再送制御のもう1つの仕組みとして高速再転送というものが用意されています。これは前述の ACK パケットを待たず次々とセグメントを送信する場合に使用されます。

TCP2-04

上図(Figure:TCP2-04)の例で見ると、受信側端末は5番目のセグメントを受け取った段階で、4番目のセグメントが未着になっていることに気がつきます。そこで、まだ受け取っていないセグメントがあることを ACK パケット(ACK 番号で分かる)にて送信側端末に通知します。しかし、これに続いて6番目、7番目のセグメントも到着するので、そのたびに未着セグメントがあることを送信側端末に通知します。一方送信側では、同じ ACK 番号を3回受け取った時点で届いていないセグメントがあることを知ります。そして、その未着となっているセグメントから再送信をします。抜けているセグメントのみ送信するのではなく、抜けているセグメント以降を全て送信し直すのです。なお、1回目、2回目の ACK パケットで再送信しないのは、受信側へのセグメントの到着順序が入れ替わっただけである可能性が大きいからです。

広告

Copyright (C) 2004 七鍵 key@do.ai 初版:2004年12月26日 最終更新:2004年12月26日