TCPはコネクション型のプロトコルで、通信に先立ってコネクションを確立するコネクション型通信を提供します。 コネクションを確立すると、通信経路にVC(Vitual Circuit)と呼ばれる仮想通信経路が作られます。 VCではデータをセグメントと呼ばれるある大きさの単位に分割して送信します。 セグメントを送信するごとに受信側は確認応答を行い、もし確認応答が受信側に届かなかった時は、通信失敗として、再送処理を行います。 今回はこの再送処理を見ていきます。
はじめに
クライアント:mac(192.168.10.2) サーバ:mio.yokohama(202.181.99.77) クライアントからサーバへのHTTPリクエストパケットをクライアント側のwiresharkでキャプチャします。 確認応答という言葉を使っていますが、ACKと同じ意味です。
TCPの再送処理
AliceからBobにデータを送る例を見てみましょう。 再送処理は送信失敗が発生する場面によって、処理が異なります。 
パターン1(正常な通信)
セグメント1は正常に伝送できました。
パターン2(セグメントが送信失敗する)
セグメント2はセグメントの送信が失敗しています。 当然Bobには届いておらず、確認応答も帰ってこないので、Aliceは送信失敗と判断し、再送します。 再送すると確認応答が返ってきたので、送信成功です。
パターン3(セグメントは送信成功しても、確認応答が送信失敗する)
セグメント3はAliceからBobへの伝送は成功しており、Bobは確認応答を返しました。 しかし、確認応答が送信失敗になり、Aliceに届きません。 Aliceは確認応答が返ってこないので、送信失敗と判断し再送します。 再送セグメントはBobに届きますが、重複したフレームになるので破棄して確認応答を返します。 確認応答がAliceに返ってきたので、送信成功です。
実際の通信パケット
これがキャプチャしたパケットです。 フレームを順番に見てきます。
フレーム1,2,3(コネクション確立)
フレーム1,2,3はコネクションを確立する3ウェイハンドシェイクです。
フレーム4(リクエスト—GETメソッド)
コネクション確立後、フレーム4でGETメソッドがクライアントからサーバへ送られています。
フレーム5(ウィンドウアップデート)
フレーム5ではサーバがクライアントにウィンドウサイズを伝えています。 これはウィンドウ制御といい、ウィンドウサイズに収まる数のフレームはACKをいちいち返すことなく、連続して伝送できる仕組みです。 フレームごとに応答確認をする必要がないので、応答の待ち時間を削減できます。
フレーム6(再送処理)
フレーム6に[TCP Retransmission]とあります。
これは再送フレームで、詳細を見ると、フレーム4の再送であると分かります。 フレーム4の応答確認が帰ってこなかったので、再送したことになります。 フレーム4とフレーム6のフレーム長がどちらも467byteと同じなのも再送フレームだからです。 また、PSHフラグが立っているので、このパケットを受け取ると、ウィンドウ制御によらず、すぐに処理しなければなりません。
フレーム7(再送に対する応答)
フレーム6で再送した次のフレーム7で、今度はちゃんと応答確認フレーム7が帰ってきました。
まとめ
応答確認のおかげで、データ伝送の信頼性が高められていることが分かりました。 次回はウィンドウ制御です。
参考
Wiresharkを使った解析|ネットワーク入門サイト TCP/IP - TCP Window Control / Flow Control|ネットワークエンジニアとして @network Cisco・アライド実機で学ぶ|TCPの制御(フロー制御・ウィンドウサイズ)その2