TCP / UDP の特徴
TCP と UDP は OSI 参照モデルではトランスポート層に位置するプロトコルである。いずれも通信する両端のアプリケーション間でパケットを送受信する機能を有するが、TCP はコネクション型、UDP はコネクションレス型のプロトコルとなる。
IP ヘッダにおける IP アドレスにより両端のホストが識別され、TCP/UDP ヘッダ中のポート番号によりアプリケーションが識別される。
TCP はコネクションを確率した後、コネクション単位でパケットの順序管理を行う。エラーを検知した際は、再送要求を行うことで、信頼性の高い通信を実現している。加えて連続転送やフロー制御など、様々な機能を有している。
UDP はコネクションを確率しないので、IP 同様パケット単位の通信を行う。そのため、アプリケーションデータ単位の通信では信頼性が保証されていない。
その代わり、TCP よりもヘッダが簡略化されている分、1 パケットに占めるデータの割合が大きくなる傾向がある。さらに、確認応答処理や再送処理に伴う遅延が発生しない。
よって、単位時間あたりに通信できるデータ量は TCP よりも UDP の方が多くなる傾向を示す。それゆえ、DNS など、概して要求/応答の 1 往復で事足りるプロトコルで使用頻度が高い通信に用いられる。
また、音声通信など、多少のパケット廃棄は許容できるので再送処理は不要であるものの、大幅な遅延が問題視される通信に用いられる。
なお、パケット廃棄の検知及び対応は、必要ならアプリケーション層で行う。
TCP ヘッダ
TCP ヘッダのフォーマットを以下に示す。
- Source Port (16) / Destination Port (16)
通信を行うアプリケーションを識別する番号。0 ~ 1023 までの範囲は Well-known Port Number と呼ばれ、広く利用されているアプリケーションプロトコルで利用されているもの。 - Sequence Number (32)
データ通信フェーズの期間中、送信したデータの順番はシーケンス番号により管理されている。
コネクションが確立された後、両端はシーケンス番号、確認応答番号 (相手のシーケンス番号) を保持している。
パケットを送信するとき、自分が保持しているシーケンス番号、確認応答番号をヘッダに格納する。その後、送信側は自分が保持しているシーケンス番号にデータのバイト数を加算する。
なお、コネクション確立フェーズの SYN フラグ、コネクション切断フェーズの FIN フラグも 1 バイト分のデータと見なし、シーケンス番号に加算される。
シーケンス番号、確認応答番号のサイズは 4 バイトであり、32 ビット値が巡回的に使用される。(0xFFFFFFFF の次の値は 0x00000000 となる) - Acknowledgment Number (32)
次に受信すべきシーケンス番号。送信側は、返された確認応答番号と次に送るシーケンス番号が同じであることを確認すれば、正常に通信が行われているか確認することができる。 - Data Offset (4)
TCP セグメント内のデータ開始位置。事実上、ヘッダ長と同じ意味を持つ。
単位は 4 バイトとなる。オプションがない場合、TCP ヘッダは 20 バイトとなるため、0x05 が格納される。 - Reserved (3)
将来のために予約されており、0 が格納される。 - Control Flag (9)
コントロールビットとも呼ばれ、9 ビットで構成されている。
NS (ECN-nonce) / CWR (Congestion Window Reduced) / ECE (ECN-Echo):
輻輳が発生していることを相手に通知する機能。明示的輻輳制御 (ECN: Explicit Congestion Notification) で使用する
URG (Urgent):
このビットが立っている場合、緊急に処理すべきデータが含まれることを示している。
ホストが緊急データを受信すると受信アプリケーションの割り込みが入るので、アプリケーションは緊急データをただちに処理する。
ACK (Acknowledgement):
このビットが立っている場合、Acknowledgment Number フィールドが有効である。
コネクション確立フェーズで最初に送られるパケット以外はこのビットは必ず 1 になっている。
PSH (Push):
このビットが立っている場合、受信したデータはバッファリングされずに、ただちに上位アプリケーションに渡される。
例えば HTTP ではサーバへファイル取得を要求するが、サーバから返信される TCP セグメントには PSH がセットされている。
よってクライアント OS は受信したデータをブラウザに渡すことができる。(複数デグメントに分割された場合は最後のセグメントに PSH がセットされている )
RST (Rest):
このビットが立っている場合、コネクションが強制的にリセットされる。
SYN (Synchronize):
コネクション確立フェーズで使用される。
このビットが立っている場合、コネクション確立要求を意味している。
FIN (Fin)
コネクション切断フェーズで使用される。
このビットが立っている場合、コネクション切断要求を意味している。
なお、NS / CWR / ECE は RFC3168 で新たに定義されている。
- Window (16)
ウィンドウサイズとは受信確認をまたずに送信できるデータサイズの最大値であり、簡単には「受信バッファの空き容量」と言い換えられる。
通常、ウィンドウサイズの初期値は TCP の MSS (Max Segment Size) を整数倍した値が設定されるが、通信中の受信状態に応じて変動する。
ホストは、送信時に現在の空き容量をウィンドウサイズに格納して相手に通知する。相手ホストは通知されたウィンドウサイズに達するまで、確認応答を待たずにデータを連続転送することができる。
確認応答パケットを受けると、次はそのパケットに格納されているウィンドウサイズまでデータを連続転送する。
そのパケットに格納されている確認応答番号は、次に受信すべきシーケンス番号を示しているので、送信側から見た連続転送可能なデータ範囲は、確認応答番号を起算とするウィンドウサイズ分となる。
確認応答のたびに、連続転送可能な範囲がウィンドウで示され、これが次第にスライドしていく。このような方式をスライディングウィンドウ方式という。
この方式では、確認応答をまつ時間を省くことで単位時間あたりのデータ転送量が増すので、効率の良いデータ通信を実現することができる。
なお、受信ホストのウィンドウサイズが 0 と通知された場合、送信ホストはこれ以上パケットを送信できない。(ゼロウィンドウ)
受信側ホストは、ウィンドウサイズが 0 より大きくなったら送信側ホストに通知する。これをウィンドウ更新と呼び、データを格納しない確認応答パケットが用いられれ、ウィンドウ領域に更新された値がセットされている。
この仕組みにより、送信を再開できる。しかし、ウィンドウ更新パケットが消失するリスクに備えて、送信側ホストは定期的にウィンドウプローブと呼ばれる 1 バイト分のデータを格納したパケットを送信して、確認応答パケットの返信を促す。
その確認応答パケットのウィンドウサイズが 0 より大きな値に更新されていれば送信を再開する。
- Checksum (16)
TCP セグメント (TCP ヘッダと TCP データ) のビットレベルの整合性チェックを行う。 - Urgent Pointer (16)
TCP セグメント内の緊急データの位置を示す。
UDP ヘッダ
UDP ヘッダのフォーマットを以下に示す。
- Source Port (16) / Destination Port (16)
アプリケーションを識別するためのポート番号。 - Length (16)
単位はバイトで、データグラム (UDP ヘッダと UDP データ) の長さ。 - Checksum (16)
データグラムのビットレベルの整合性チェックを行う。