TCP
- TCPは、コネクション指向の信頼性の高いバイトストリーミングサービスを提供します。
- TCP 接続では、2 つのパーティだけが互いに通信します。TCPではブロードキャストとマルチキャストは使用できません。
- TCPは、チェックサム、確認応答、再送信を使用して、信頼性の高い伝送を保証します。
- TCPはデータをセクションにソートし、累積検証を使用して、データが同じ順序で重複していないことを確認します。
- TCPは、輻輳制御のためにウィンドウのサイズを動的に変更することにより、フロー制御を実装するためにスライディングウィンドウメカニズムを使用します。
注: TCPは、データが相手によって受信されることを保証するものではありません。したがって、TCPは100%信頼できるプロトコルではありません。TCPが提供できるのは、データの確実な配送か、失敗の確実な通知だけです。
回の握手と4回のウェーブ
いわゆるトリプルハンドシェイクとは、TCP接続を確立するためにクライアントとサーバーが合計3つのパケットを送信する必要があるという事実を指します。
3つのハンドシェイクの目的は、サーバーの指定されたポートに接続し、TCP接続を確立し、接続の双方のシーケンス番号と確認番号を同期させ、TCPウィンドウサイズ情報を交換することです。ソケットプログラミングでは、クライアントがconnect().を実行すると、3つのハンドシェイクが開始されます。
- 最初のハンドシェイク:
クライアントは、SYNフラグを1の位置にして、クライアントが接続しようとするサーバのポートを指定し、パケットヘッダのシーケンス番号フィールドに格納されている初期シーケンス番号Xを持つTCPパケットを送信します。
送信後、クライアントはSYN_SEND状態になります。
- 2回目のハンドシェイク:
サーバーはこれに応答して確認応答パケットを送り返します。つまり、SYNフラグビットとACKフラグビットは両方とも1です。 サーバー側は、自分のISNシーケンス番号を選択してSeqフィールドに入れると同時に、確認応答シーケンス番号をクライアントのISNに1を加えたもの、つまりX+1に設定します。送信が完了すると、サーバー側はSYN_RCVDステートに入ります。
- 3回目のハンドシェイク
クライアントは、SYNフラグビットを0に、ACKフラグビットを1にして、再度確認応答パケットを送信し、サーバーからのACKのシリアル番号フィールドに+1を入れ、OKフィールドに入れて相手に送信し、ISNのデータフィールドに+1を入れます。
送信後、クライアントはESTABLISHED状態になり、サーバもパケットを受信するとESTABLISHED状態になり、TCPハンドシェークは終了します。
つのハンドシェイクのプロセスを図にすると以下のようになります:
TCPコネクションの切断には4つのパケットを送信する必要があるため、4つのハンドシェイク(修正3ハンドシェイク)とも呼ばれます。ハンドシェイクは、クライアントとサーバーのどちらかが開始することができ、ソケットプログラミングでは、どちらかがclose()オペレーションを実行することでハンドシェイクを生成することができます。
- 最初の波
クライアントがコネクションを閉じたいと仮定すると、クライアントはFINフラグの位置が1のパケットを送信し、送信するデータはもうないが、データはまだ受信できることを示します。
送信後、クライアントはFIN_WAIT_1ステートに入ります。
- 第2波
サーバ側は、クライアントのFINパケットを確認するために、クライアントのコネクションを閉じる要求を受け付けたが、まだコネクションを閉じる準備ができていないことを示す確認パケットを送信します。
送信後、サーバー側はCLOSE_WAIT状態になり、クライアントはこの確認パケットを受信した後、FIN_WAIT_2状態になり、サーバー側がコネクションを閉じるのを待ちます。
- 第3波
サーバー側は接続を閉じる準備ができたら、FINに1をセットしてクライアント側に接続終了リクエストを送信します。
送信後、サーバー側はLAST_ACK状態になり、クライアントからの最後のACKを待ちます。
- 第4波
クライアントはサーバー側からシャットダウン要求を受信し、確認応答パケットを送信し、TIME_WAIT状態になり、再送を要求するACKパケットの可能性を待ちます。
この確認パケットを受信すると、サーバー側は接続を閉じてCLOSED状態になります。
一定時間待ってもサーバからACKが来ないので、サーバは正常に接続を閉じたと判断し、クライアント自身が接続を閉じてCLOSED状態になります。
4つの波の図は以下の通り。