1

これが私の問題です:

ゲームサーバーとの間でデータを送受信できるudpクラスがあります。

しかし、サーバーはクライアントごとに500ミリ秒ごとに1つのリクエストしか許可しないことがわかりました。したがって、2つの要求を続けて送信すると、サーバーは最初の要求にのみ応答し、2番目の応答が得られないことを知る方法がありません。

そこで、送信部分を保護するためにミューテックスを作成しました。データを送信するときは、スレッドを使用してミューテックス500msをブロックします。

このクラスはスレッドによって使用されるため、mutexを使用します。

しかし、これは実際にはうまく機能せず、受信がスタックすることがあります。

誰かがこれを行うためのより良い方法を持っているかどうかを知りたいだけです。

私の英語をありがとう、そしてごめんなさい。

編集:私はtcpプロトコルを使用できません、私はudpでこれを行う必要があります。また、最適な方法が必要です。受信データをできるだけ早くビューフォームに取得する必要があります。udpとスレッドで見つけたネット上のすべてのトピックを監視していますが、この特定のケースは見つかりません。

4

3 に答える 3

1

ある程度の頻度でしか送信できないことがわかっている場合は、通話をブロックして送信してみませんか。そして、必要な時間寝ます。

class UDP {
  int _lastTime = 0;
  int MIN_DELAY = 500;

  public void send() {
    lock(this) {
      int duration = now() - _lastTime;
      if (duration < MIN_DELAY) {
        sleep(MIN_DELAY - duration);  
      }
      realSend();
      _lastTime = now();
    }
  }
}
于 2010-12-07T16:53:33.373 に答える
1

UDPを使用する場合、送信する特定のメッセージに対する応答が得られると思い込まないでください。また、メッセージが実際に受信されるとか、複数のメッセージが送信したのと同じ順序で受信されると想定しないでください。そのため、UDPは、情報の損失を許容できるプロトコルにのみ適しています。整合性を維持したい場合は、再試行を許可する必要があります。その時点で、TCPを使用したほうがよいでしょう(問題に選択肢があったと仮定します)。

プロトコルの詳細に関する詳細情報がなければ、優れたソリューションを推奨することは困難です。単純な「ステータスポーリング」スタイルのメッセージの場合、1つのオプションは、ポーリングメッセージを一定の間隔で送信し、応答が送信されるメッセージとの関係を無視して、到着時に応答を処理することです。

于 2010-12-07T16:44:21.310 に答える
0

他の人が指摘しているように、UDPメッセージが配信されるとは想定できません。これにより、受信時にコードがハングする可能性があります。たぶん、ソケットのReceiveTimeoutを設定するだけで、アプリケーションには十分でしょう。

または、送信するメッセージをキューに入れ、500ミリ秒ごとに1つだけ送信し、一定時間後に応答が得られるまでメッセージを再試行する(やや複雑な)方法を設定することもできます。このルートを使用する場合は、次の一般的なポイントを中心に設計します。

  • 非同期UDPを使用します。
  • 送信/受信する実際の情報(たとえばMsgObject)の構造体/クラスを作成します。これには、最後に送信された時間に関する情報も含まれます。
  • このMsgObjectをAsyncStateオブジェクトとして使用します。
  • すべてのアクティブなMsgObjectのスレッドセーフキュー/リストを管理します。つまり、送信を要求されたが応答が受信されていないメッセージ。
  • キュー/リストを定期的に(この場合は500ミリ秒ごとに)チェックして、送信する新しいメッセージや再送信する必要のあるメッセージがあるかどうかを確認する簡単なタイマーを用意します。
  • 非同期受信機能で、応答を受信したMsgObjectをキュー/リストから削除します。
于 2010-12-07T17:31:17.287 に答える