3

クライアント側のカウンター変数があるとします。サーバーにリクエストを送信するときは、この変数の値を送信してから、値を 1 つ増やします (サーバーへの次のリクエストのために)。サーバーはこのカウンターを独立して追跡し、クライアントから送信されたカウントがそれ自体 (サーバー側) のカウントのコピーよりも 1 多いことを確認します。これはすべてうまくいきますが、次の状況を考えてみてください。

  1. クライアントは、たとえば 23 をサーバーに送信します。
  2. サーバーは 23 を受け取り、それを検証して、独自のカウンターを 23 に増やします。
  3. サーバーは All-Okay コードをクライアントに返します

-しかし-

サーバーからクライアントへの途中で、リターン コードが破損します。したがって、クライアントは、サーバーがカウンターを更新しなかったと考え、クライアント側のカウンターを 23 のままにします。この時点以降、クライアントとサーバーは同期していません。

このような破損/エラーの可能性に直面しても機能する堅牢なスキームを知っている人はいますか?

ありがとう、
キャメロン

4

3 に答える 3

2

直線的に増加するカウンターを使用する代わりに、64 ビット以上のエントロピーのランダムな「ナンス」値を使用できます。サーバーがクライアントからリクエストを受信すると、サーバーはノンスが最後にクライアントに送信したものと一致するかどうかを確認します。その場合、リクエストは処理され、サーバーはレスポンスで送信する新しいランダムナンス値を生成します。

サーバーは、クライアントに送信する最後の 2 つの nonce 値を保持できます。クライアントが古い値を送信すると、サーバーは、クライアントへの最新のメッセージが失われた可能性があると見なします。

上記の方法は、2 つの異なるクライアントが同じ資格情報を使用してサーバーと通信するのを防ぐことを目的としていることを前提としています。nonce メソッドを使用する利点は、次の値を簡単に予測できないことです。

于 2008-10-18T23:19:25.687 に答える
1

簡単な答えは、クライアントまたはサーバーのいずれかをリソースの所有者にすることです。両方が独自のリソースのコピーを作成するのではありません。

ただし、TCP のような信頼できるプロトコルを使用している場合は、メッセージがクライアントに届かないことを心配する必要はありません。

ただし、クライアント/サーバーの作業を行う場合に従うべき良いことは、すべての操作をべき等にすることです。つまり、各関数は、副作用なしで 1 回または複数回呼び出すことができます。この場合、「インクリメント」機能はまったくありません。代わりに、「set」関数があります。

于 2008-10-18T23:16:01.357 に答える
1

サーバーがサーバーカウンターの更新を確認するまで、クライアントにローカルコピーを更新させないのはどうですか。

そう:

クライアントは次の値を計算する クライアントは次の値をサーバーに送信する サーバーは次の値が有効であることを確認する (まだ確認されていない) サーバーはカウンターを次の値に更新する (必要な場合) サーバーはクライアントに次の値が受信されたことを通知する クライアントはローカルカウンターを次の値に更新する

サーバーがクライアントの更新を受信しない場合、クライアントは計算された次の値を再送信するだけです。クライアントが次の値の確認を受信しない場合、次の値を再送信しますが、既にそれを確認したサーバーは更新せず、確認するだけです。最終的に、クライアントはサーバーのメッセージを確認して続行します。これは、失われたメッセージの場合をカバーしています。

破損が心配な場合は、メッセージのチェックサムを計算し、それも送信してください。受信時にチェックサムを再計算し、送信されたものと比較します。ただし、通常はネットワーク スタックがこれを行います。そのため、独自のプロトコルを実行していない限り、あまり心配する必要はありません。

于 2008-10-18T23:31:28.533 に答える