TCP通信の流れ

トラブル発生時、通信がどこで止まっているのか確認が必要な時があります。本項では確認出来るようにTCP通信の流れを説明します。

 応用編の「TCP・UDP」ではシーケンス番号でパケットが順番通り来ているか判断出来ると説明しましたが、実際には以下のようになっています。

TCP通信の流れ1

 受信パケットのシーケンス番号とAck番号を入れ替える事が基本ですが、ポイントとしては受信側はAck番号を相手のシーケンス番号に受信したbyte数プラスして返す事です。このようにしてシーケンス番号は増えていき、どのbyteまで受信が完了したか送信側で把握出来るようになっています。

 尚、図では簡単のため1000byeにしていますが、実際にはフラグメントがなければ最大に送れるデータ量であるMSS、例えば1460byte等で送ります。

 一回一回Ackが返ってくるのを待って次のパケットを送ると遅くなります。

 このため、実際の通信では複数のパケットを一気に送っています。

TCP通信の流れ2

 一気に送ると言っても、受信側で受け取れない程送っては意味がありません。このため、送受信出来る量を決めてから送信しています。

 この時のやり取りを詳しく見ていくと、まずは3ウェイハンドシェイクで一度に受信出来る量とMSSを決めます。図では9,000byteのデータを送る際、青枠で示した部分がMSSで1,000byte、赤枠で囲った部分の3,000byteが一気に受信出来る量になりますが、太枠部分をウィンドウサイズと言います。

TCP通信の流れ3

 3パケットを一気に送ってAckが返ってきた場合、ウィンドウを下にスライドさせます。

TCP通信の流れ4

 赤枠部分がこれから送る部分で、赤枠の上は既にデータ送信が終わった部分です。このようにしてウィンドウをスライドさせながら全てのデータを送るため、このやり方をスライディングウィンドウと言います。

 ウィンドウサイズは上の図では3,000byteですが、実際のサイズは64Kbyte、若しくはそれ以上になり、設定によって変更可能です。

 スライディングウィンドウでデータを一気に送る場合、受信する度にAckで応答するとAckの数がとんでもない数になります。

 このため、Ackを何度かに1度送るようになっています。例えばWindowsでは「前に受信したデータに対してACKを送信していない場合」、つまり2回送られてくると1回Ackで応答します。

TCP通信の流れ5

 これを遅延Ackと言います。

 スライディングウィンドウでは、Ackを待たずにウィンドウサイズ分を一気に送るため、遅れて到着するAckを見て送信側は正常に受信出来ているか判断し、正常に受信出来ていない場合は再送します。

TCP通信の流れ6

 スライディングウィンドウによって一気に送ってAckでの応答が同じ番号が何回か続くと、届いていないと判断して再送する仕組みになっていますが、シーケンス制御を見て分かる通りAck番号ではどこまで受信が完了したかしか分かりません。

 このため、Ack番号だけで判断した場合は最初から送り直そうとします。

TCP通信の流れ7

 ①が届いた後は既に届いているデータまでAck番号を上げるため実際には最初から全て送り直す事にはなりませんが、効率的ではありません。

 このため、SACKというオプションにより、どこからどこまでが抜けがあるか分かるようになっています。送信側はSACKオプションを確認する事で抜けがあったパケットだけ再送すればよい事が分かります。

 SACKオプションは応用編「TCP・UDP」で示したTCPヘッダーの構造のオプション部分に組み込み可能です。

サイト関連1

応用編「TCP・UDP
  • このエントリーをはてなブックマークに追加