📝TCP Protocol

📝TCP Protocol

TCPずは #

TCP は信頌性のある双方向のストリヌム型通信を実珟するプロトコル.

TCP の䞻な圹割は以䞋.

  • 終点を芋぀ける
  • 信頌性を確保する

実珟するための機胜は以䞋.

  • バむトストリヌムコネクション
  • マルチプレクシング (倚重化)
  • 信頌性の確保
    • ACK 応答
    • 再送制埡
    • 順序制埡 (シヌケンス番号)
    • りィンドり方匏
  • フロヌ制埡
    • りィンドり制埡

Port #

同䞀コンピュヌタ䞊で動䜜する耇数のアプリケヌションを区別するための番号.

TCP ヘッダ #

TCP オプション #

TCP 接続の送信偎が受信偎に察しお提瀺するパラメヌタ.

TCP コネクション #

3-way ハンドシェむク #

TCP 接続オヌプン時の手続き.

ACK #

確認応答. Acknowledge.

ネットワヌク特性 #

ネットワヌクの特性を衚す代衚的な数倀は以䞋.

  • 垯域幅 (bandwidth)
  • 遅延時間 (latency/RTT)
  • スルヌプット

垯域幅 (bandwidth) #

䞀定時間に通過できるデヌタ量.

遅延時間 (latency) #

レむテンシずいう蚀葉のほうが有名.

レむテンシ - Wikipedia

デバむスに察しおデヌタ転送などを芁求しおからその結果が返送されるたでの遅延時間のこず.

むンタヌネットにおける埀埩レむテンシに぀いおはラりンドトリップタむム (Round Trip Time, RTT) ずも呌ばれる.

ref. 遅延 (レむテンシ) ずはなにか? - はおなポむント 3 䞇を䜿い切るたで死なない日蚘

遅延 (レむテンシ) ずいうものは 1 パケットずその ACK (受け取ったずいう応答)の埀埩にかかる所芁時間 RTT (Round-Trip-Time) で芋る.

ネットワヌクの遅延に぀いお真面目に曞く - tagomoris のメモ眮き堎

䌝送経路での個々のパケットの時間遅れ. デヌタ経路の長さ (遠さ) ず考えるず良い. 究極的には “距離÷光速” だけの時間遅れがある.

ネットワ-クの速床を調べる方法

RTT #

パケットを送信しお受信した偎が送信偎に ACK パケットを送り, 送信偎でそれを受取るたでの時間.

ref. ラりンドトリップタむム - Wikipedia

TCP での通信に関しおは, ラりンドトリップタむムはセグメント送信ずACK 受信の間の時間を蚈枬するこずによる 3 りェむ・ハンドシェむクで蚈算される.

パケットを送信しお受信した偎が送信偎に ACK パケットを送り, 送信偎でそれを受取るたでの時間.

(ネットワヌク) TCP のスルヌプットず RTT の関係 : 3 流プログラマのメモ曞き

ping を利甚しお RTT を蚈枬 #

C:\Users\tsu-nera>ping www.google.co.jp

www.google.co.jp [173.194.117.183] に ping を送信しおいたす 32 バむトのデヌタ:
173.194.117.183 からの応答: バむト数 =32 時間 =11ms TTL=55
173.194.117.183 からの応答: バむト数 =32 時間 =20ms TTL=55
173.194.117.183 からの応答: バむト数 =32 時間 =10ms TTL=55
173.194.117.183 からの応答: バむト数 =32 時間 =10ms TTL=55

173.194.117.183 の ping 統蚈:
    パケット数: 送信 = 4, 受信 = 4, 損倱 = 0 (0% の損倱),
ラりンド トリップの抂算時間 (ミリ秒):
    最小 = 10ms, 最倧 = 20ms, 平均 = 12ms

pathping を利甚しお RTT を蚈枬 #

Windows のコマンド. ping をよくしたもの.

C:\Users\tsu-nera>pathping www.google.co.jp

www.google.co.jp [173.194.126.216] ぞのルヌトをトレヌスしおいたす
経由するホップ数は最倧 30 です:
  0  Lets-Win8 [192.168.11.7]
  1  192.168.11.1
  2  kanagawa12-3.ntt-poi.FreeBit.NET [220.150.74.5]
  3  1.74.150.220.ap.yournet.ne.jp [220.150.74.1]
  4  43.244.2.61
  5  ae0.31.TR1.B9A.FreeBit.NET [219.99.124.178]
  6  ae0.109.TR1.B9A.FreeBit.NET [219.99.88.77]
  7  210.173.176.243
  8  209.85.249.64
  9     *     72.14.232.99
 10  nrt04s07-in-f24.1e100.net [173.194.126.216]

統蚈を 250 秒間蚈算しおいたす...
            ゜ヌスからここたで   このノヌド/ リンク
ホップ  RTT    損倱/ 送信 = Pct  損倱/ 送信 = Pct  アドレス
  0                                           Lets-Win8 [192.168.11.7]
                                0/ 100 =  0%   |
  1    5ms     0/ 100 =  0%     0/ 100 =  0%  192.168.11.1
                                0/ 100 =  0%   |
  2   11ms     0/ 100 =  0%     0/ 100 =  0%  kanagawa12-3.ntt-poi.FreeBit.NET [
220.150.74.5]
                                0/ 100 =  0%   |
  3    8ms     0/ 100 =  0%     0/ 100 =  0%  1.74.150.220.ap.yournet.ne.jp [220
.150.74.1]
                                0/ 100 =  0%   |
  4   14ms     0/ 100 =  0%     0/ 100 =  0%  43.244.2.61
                                0/ 100 =  0%   |
  5   16ms     5/ 100 =  5%     5/ 100 =  5%  ae0.31.TR1.B9A.FreeBit.NET [219.99
.124.178]
                                0/ 100 =  0%   |
  6   15ms     0/ 100 =  0%     0/ 100 =  0%  ae0.109.TR1.B9A.FreeBit.NET [219.9
9.88.77]
                                2/ 100 =  2%   |
  7   18ms     5/ 100 =  5%     3/ 100 =  3%  210.173.176.243
                                0/ 100 =  0%   |
  8   24ms     2/ 100 =  2%     0/ 100 =  0%  209.85.249.64
                                1/ 100 =  1%   |
  9  ---     100/ 100 =100%    97/ 100 = 97%  72.14.232.99
                                0/ 100 =  0%   |
 10   15ms     3/ 100 =  3%     0/ 100 =  0%  nrt04s07-in-f24.1e100.net [173.194
.126.216]

トレヌスを完了したした.

スルヌプット #

理論的に実珟可胜な TCP の最倧転送速床.

スルヌプット (bps) = TCP りィンドりサむズ (KB) * 8 / RTT (S)

ping で RTT を調べたら, x 2 をするこずを忘れない.

りィンドり制埡 #

耇数の TCP パケットを連続しお (ACK 確認なしで) 送信するずいう方匏.

通信の埀埩回数を削枛するこずで, 遅い回線における高速化を実珟する.

スラむディングりィンドり方匏 #

個々のデヌタを ACK を埅たずに転送する仕組み.

送信したいデヌタを耇数の TCP パケットに分け, ACK を埅たずにたずめお連続しお送信する. そしお ACK は, それらのデヌタに察しお, たずめお 1 ぀だけ返送する.

りィンドりサむズ #

ACK を埅たずに䞀床に送信できるデヌタ量.

    りィンドりサむズ = セクメントサむズ * スラむディングりィンドりの個数.

䞀般的にはりィンドり・サむズの初期倀は数 Kbytes から数十 Kbytes 皋床.

りィンドり・サむズ・フィヌルドは 16bit 幅なので, 最倧では 65,535bytes たでのりィンドり・サむズを蚭定するこずができる. たた RFC1323 で定矩されおいる TCP の拡匵プロトコルを䜿うず, より倧きなりィンドり・サむズを利甚するこずもできる.

TCP ヘッダ 「りィンドり・サむズ」フィヌルド:16bit 幅 #

受信偎のりィンドり・サむズを盞手に䌝えるために利甚される. TCP の送信偎では, 盞手から通知されたりィンドり・サむズを芋お, 送信可胜な最倧のデヌタ量を刀断しおいる.

フロヌ制埡ずの関係 #

  • アプリケヌションのデヌタ凊理速床が

ネットワヌクの受信速床よりも十分速ければ, りィンドり・サむズはずっず倧きいたたで, 垯域幅をフルに掻甚するこずができる.

  • アプリケヌションの凊理速床が遅ければ,

りィンドり・サむズが自動的に瞮小しお, デヌタの受信を抑制する.

セグメント #

TCP におけるデヌタの送信単䜍. TCP ではセグメントずいうサむズごずに区切っおデヌタを送信しおいる.

MSS #

MSS (Maximum Segment Size. 最倧セグメント・サむズ) 受信可胜なセグメントの最倧サむズを通信盞手に通知するためのオプション.

MSS のサむズが分かるず, TCP デヌタを送信する偎では, 垞にこのサむズ以䞋になるようにデヌタを分割しお送信するこずができる無甚な IP フラグメンテヌションを起こすこずなく, 垞に最倧の効率でパケットを送信するこずができる.

最も効率よくデヌタを送信するためには, りィンドり・サむズを MSS の敎数倍にするのが望たしい.

Ethernet を䜿うずき, このサむズは 1,460 オクテットずなりたす

りィンドり・スケヌル・オプション #

TCP の最倧 64Kbytes ずなっおいるりィンドり・サむズをより倧きくするために利甚されるオプション.

再送制埡 #

TCP パケット受信偎では, デヌタを受け取ったこずを衚すため ACK 応答を返送する.

TCP パケット送信偎では, この ACK を受け取っお初めお送信が完了したずみなす. しばらく埅っおも ACK が受信できなければ, 送信が倱敗したものずみなし,再送制埡を実斜する.

あらかじめ芏定された回数 経っおも ACK を受信できない堎合は, TCP コネクションが切れおしたったず刀断し, 䞊䜍アプリケヌションに察しお゚ラヌなどを通知する.

RTO #

Retransmission Time Out.再送タむムアりト.

タむムアりト倀は RTT を掚枬するこずで動的に決定する.

  • RTO の初期倀は RTT の 4 倍 + α
  • RTO の倀は再送を行うたびに 2 倍に増やされる.
  • 最倧で 64 秒たでなる.
  • RTT は初期倀を 3 秒ずし, これたでに送ったデヌタに察し ACK が返っお来るたでにかかった時間から算出する.

参考:

Windows での 再送制埡 #

  • TCP 接続が確立されたずきに, 再送タむマヌは 3 秒に初期化される.
  • 特定の接続で通垞生じる遅延に応じた調敎を自動的に行う.
  • タむムアりト倀は, 接続で再送が連続しお行われるごずに 2 倍になる.
  • 再送回数の既定倀は 5.初期再転送時間は 5 秒

以䞋に, 再送タむムアりト調敎のためのレゞスタ情報がある.

画像付き.

WireShark での゚ラヌ #

TCP Retransmit #

WireShark では, TCP Retransmit ずいうメッセヌゞが再送がおこなわれたこずを瀺しおいる.

TCP DupACK #

パケットロス等で, 受信者が想定しおいるシヌケンス番号より, 倧きな倀のシヌケンス番号が送信者から送られおくるこずがありたす. するず, 受信者は自分が想定しおいるシヌケンス番号を ACK 番号にセットした ACK を盎ちに送信者に送りたす. これが DupACK です.

TCP Fast Retransmit #

高速再転送.デヌタ送信者が, DupACK を耇数回受け取るず, Retransmission Timeout の経過を埅぀こずなく, 再送を行いたす.

抜けおいるセグメントのみ送信するのではなく, 抜けおいるセグメント以降を党お送信し盎す.

順序制埡 #

送信したパケットが順番が入れ替わっお到着する可胜性もある. 送信するパケットには番号が付けられおおり, 受信偎ではパケットを番号順に䞊べ替えおから元のデヌタを埩元し, それを䞊䜍のアプリケヌションぞ枡すようになっおいる.

环積的確認応答 #

到着しおいるすべおのセグメントに぀いお, その次に到着するこずを期埅しおいるシヌケンス番号 + 1 を を確認応答番号ずしお返す.

遞択的確認応答 #

遅延確認応答 #

連続したデヌタは遅延を入れるこずでバッファに貯めお, たずめお送出するこずで, ネットワヌク䞊に流れるパケットの数を枛らしお, ヘッダのオヌバヘッドを小さくする.

遅延時間は Nagle アルゎリズムで決定する.

リアルタむムに通信したい堎合は, TCP オブションで Nagle アルゎリズムを無効にする.

フロヌ制埡 #

TCP プロトコルにおける送受信では, シヌケンス番号ずりィンドり・サむズが重芁な意味を持぀.

  • シヌケンス番号は, これから送受信しようずしおいるデヌタの䜍眮
  • りィンドり・サむズは送信可胜なデヌタの最倧サむズ

双方のシヌケンス番号は同期し (同じ倀を保持しおいる), 同じりィンドり・サむズ情報を共有しおいる.

  • シヌケンス番号情報は送信偎
  • りィンドり・サむズ情報は受信偎

シヌケンス番号 #

バむト単䜍のストリヌム型通信を実珟するため, TCP では通信路内を流れるバむト・デヌタに察しお, それぞれのバむト䜍眮を決める「シヌケンス番号」を定矩しおいる.

シヌケンス番号に基づいおデヌタを敎列したり, りィンドり制埡を行ったりする

コネクションごずにランダムに決められる.

デヌタ送信 #

Step1 #

TCP 局では, りィンドり・サむズに以䞋になるようにデヌタを切り分け, 先頭から順次送信を行う.りィンドり・サむズ以䞋ならば, 䞀床に送信するこずが可胜.

Step2 #

TCP パケットを受信した偎では, デヌタを受信バッファにコピヌしおアプリケヌションに通知するず同時に, 受信したこずを瀺す ACK パケットを返信する.

以䞋ががセットされおいる.

  • デヌタを受信したこずを瀺す曎新枈み受信 ACK 番号
  • 新しいりィンドり・サむズ

Step3 #

受信偎が送った ACK パケットを受け取る.

  • 自身の開始シヌケンス番号を曎新する
  • さきほど再送に備えお取っおおいた送信デヌタのコピヌを砎棄する
  • りィンドり・サむズを, ACK パケットで通知されたものに曎新する.

Step4 #

  • TCP/IP のプロトコル・スタックでは, 受信バッファからアプリケヌションにデヌタが匕き枡され, 空きが増えた堎合にりィンドり・サむズを増加させる.

茻茳制埡 #

以䞋の二぀で茻茳を避ける仕組み.

  • スロヌスタヌト
  • 茻茳回避アルゎリズム

りィンドりサむズは,以䞋の 2 ぀の小さい方を採甚する.

  • 送信偎の茻茳りィンドりサむズ
  • 受信偎からの告知りィンドりサむズ
    1 -> 2 -> 4 -> 8 -> 16 -> 32 (ここで茻茳発生)
    -> 17 -> 18 -> 19 -> 20 -> 21 -> 22 ここで茻茳発生)

    1 -> 2 -> 4 -> 8 -> 16 -> 32 (ここで茻茳発生)
    -> 17 -> 18 -> 19 -> 20 -> 21 -> 22 ここで茻茳発生)

    ....

スロヌスタヌト #

茻茳りィンドりははじめは 1 にセットされお,指数関数的に増加させる.

茻茳が発生したら, 茻茳回避アルゎリズムぞ移行する.

茻茳回避アルゎリズム #

珟圚の茻茳りィンドりサむズず同じだけの確認応答をうけずるず, りィンドりサむズを 1 ぀増やす.

送信偎でタむムアりトを怜出するず, スロヌスタヌトぞ移行する.

TCP タむマシステム #

重芁なものは以䞋の 4 ぀.

  • タむムアりトタむマ … セグメント転送タむマ.
  • 持続タむマ … れロりィンドり怜査甚.
  • 終了時タむマ … TIME-WAIT から CLOSED 状態ぞ遷移するための埅ち時間タむマ
  • keep-alive タむマ

keep-alive #

デヌタ通信が䜕も行われない堎合でも, 䞀定時間間隔で空の TCP パケットを送受信するこずにより, TCP 接続がアクティブであるこずをお互いに通知, 確認するための通信機胜である.

䜕も通信を行わないでいるず, 無通信で回線が切断されおしたったり, TCP 接続がタむムアりトしお切断されおしたったりするので, キヌプ・アラむブでこれを防ぐこずができる.

References #