TCP を確立するには 3 方向ハンドシェイクが必要ですが、切断するには 4 方向ハンドシェイクが必要です。プロセス全体を以下の図に示します。
まず、接続を確立する方法を見てみましょう。
【2017.01.04更新】この部分に間違った画像がありますが、ご容赦ください。間違った画像は削除されません。わかりました。更新に時間がかかってしまってごめんなさい! !
エラーの図は次のとおりです:
まず、サーバーセグメントが接続を受け入れた後、クライアントは接続要求メッセージを送信します。メッセージを送信し、今回のリソースを割り当てます。クライアントは ACK メッセージを受信した後、サーバー セグメントに ACK メッセージを送信し、リソースを割り当てます。これにより、TCP 接続が確立されます。 接続を解除するには?簡単なプロセスは次のとおりです:[注] 切断側はクライアント側またはサーバー側になります。
クライアントが接続中断要求を開始する、つまり FIN メッセージを送信すると仮定します。サーバーが FIN メッセージを受信すると、「クライアントには送信するデータがありません」という意味になりますが、送信するデータがまだある場合は、急いでソケットを閉じる必要はなく、送信を続けることができます。データ。したがって、最初に ACK を送信します。「クライアントにリクエストを受け取りましたが、まだ準備ができていないことを伝えてください。メッセージをお待ちください」。この時点で、クライアントは FIN_WAIT 状態に入り、サーバーからの FIN メッセージを待ち続けます。サーバーは、データが送信されたと判断すると、クライアントに FIN メッセージを送信します。「 クライアントに、データは送信されたので、接続を閉じる準備ができたと伝えてください 」。クライアントは FIN メッセージを受信すると、接続を閉じることができることを認識しますが、まだネットワークを信頼しておらず、サーバーが接続を閉じることができないことを恐れているため、ACK を送信した後に TIME_WAIT 状態に入ります。サーバーは ACK を受信しない場合、再送信できます 。「サーバーが ACK を受信すると、 切断できることがわかります 」。クライアントは 2MSL 待っても応答を受信していません。これは、サーバーが正常に閉じられたことを示しています。クライアントは接続を閉じることもできます。 OK、TCP 接続はこのように閉じられました。 プロセス全体でクライアントが経験するステータスは次のとおりです:
一方、サーバーが経験するプロセスは次のとおりです:
【注意】 TIME_WAIT 状態では、TCP クライアントが送信した最後の ACK が失われた場合、再送信されます。 TIME_WAIT 状態で必要な時間は実装に依存します。一般的な値は 30 秒、1 分、2 分です。待機後、接続は正式に閉じられ、すべてのリソース (ポート番号を含む) が解放されます。
【質問1】接続するときは3ウェイハンドシェイクですが、閉じるときは4ウェイハンドシェイクになるのはなぜですか?
回答: サーバーはクライアントから SYN 接続要求メッセージを受信すると、SYN+ACK メッセージを直接送信できるためです。 ACK メッセージは応答に使用され、SYN メッセージは同期に使用されます。しかし、接続を閉じるとき、サーバーが FIN メッセージを受信したときに、SOCKET はすぐには閉じられない可能性が高いため、最初に ACK メッセージで応答し、クライアントに「送信された FIN メッセージを受信しました。 」 FIN メッセージはサーバー側のすべてのメッセージが送信された場合にのみ送信できるため、一緒に送信することはできません。したがって、4 段階のハンドシェイクが必要です。
【質問2】TIME_WAIT状態はなぜCLOSE状態に戻る前に2MSL(セグメントの最大生存時間)を経過する必要があるのですか?
答え: 4 つのメッセージがすべて送信されており、直接 CLOSE 状態に入ることができるのは当然ですが、ネットワークの信頼性が低く、最後の ACK が失われる可能性があると想定する必要があります。したがって、TIME_WAIT 状態は、失われた可能性のある ACK メッセージを再送信するために使用されます。
以上がTCP における 3 方向ハンドシェイクと 4 方向ハンドシェイクは何を意味しますかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。