0

これは、TCP ソケットに関するかなり一般的な質問です。メッセージが TCP 経由で送信されるクライアント/サーバー アプリケーションをセットアップしました。実装は C++ POCO を介して行われますが、質問は特定の技術とは関係ありません。

メッセージは、要求 (クライアントによって開始される) または応答 (サーバーによって開始される) のいずれかです。

リクエストの構造は次のとおりです。

Message Header
Request Header
Parameters

応答には構造があります

Message Header
Response Header
Parameters

TCP は、送信されたパッケージが送信された順序で配信されることを保証していることを知っています。ただし、配信に必要な期間については何も想定できません。

両側で、読み取り/送信タイムアウトが構成されています。ここで、タイムアウト後に送信されたデータをクリーンに設定する方法を知りたいです。これを正しい言葉で表現する方法がわからないので、例を説明しましょう。

  1. サーバー S がクライアントに応答を送信します (メッセージ ヘッダー、応答ヘッダー、パラメーターがストリームに入れられます)。
  2. クライアント C は、メッセージ ヘッダーを部分的に受信します (たとえば、12 の最初の 4 バイト)。
  3. この 4 バイトを受信した後、受信タイムアウトが発生します。
  4. クライアント側では、適切な例外がスローされ、受信が停止されます。
  5. クライアントはパッケージを無効と見なします。

問題は、クライアントが別のパッケージを受信しようとすると、「古い」応答メッセージ ヘッダーの最後の部分を受信する可能性があることです。現在処理されているトランザクション (要求の送信/応答の取得) の観点から、クライアントはゴミを受け取ります。

そのため、タイムアウトが発生した後 (クライアント側かサーバー側かに関係なく)、通信は「クリーン セットアップ」で続行する必要があるようです。つまり、通信パートナーのいずれも古いパッケージ データを送信しようとしません。また、それぞれのソケットのストリーム バッファ内に古いパッケージ データが格納されていないこと。

では、そのような状況は一般的にどのように処理されるのでしょうか? これを解決するためのデザインパターン/慣用的な方法はありますか? このような状況は、HTTP などの他の TCP ベースのプロトコルではどのように処理されますか?

ネット上のすべての TCP サンプルで、この種の問題を処理する実装を見たことがありません...

前もって感謝します

4

1 に答える 1

1

クライアントが別のパッケージを受信しようとすると、「古い」応答メッセージ ヘッダーの最後の部分を受信する可能性があります。

何かを受け取った場合、彼は失敗したメッセージの残りを受け取ります。彼は他のものを受け取ることができません。特に、後で送信されたデータは、以前に送信されたデータの前または代わりに受信することはできません。信頼できるバイトストリームです。それに応じてコーディングできます。

通信は「クリーン セットアップ」で続行する必要があります。つまり、どの通信パートナーも古いパッケージ データを送信しようとしません。

あなたはそれを制御することはできません。次のメッセージが TCP ソケット送信バッファに書き込まれている場合 (send()実際にはこれだけです)、メッセージは送信され、接続をリセットする以外にそれを防ぐ方法はありません。

そのため、バイトストリーム全体が到着したときに対処するようにクライアントをコーディングするか、タイムアウトで接続を閉じて再度開始する必要があります。

于 2013-08-22T01:56:23.070 に答える