私はゲームサーバーを書いていますが、c#でクライアントコンピューター(ファイアウォールで保護されている場合)にpingを実行する方法が見つからないようです。
ゲームがそれをどのように行っているかについての情報も見つからないようです。クライアントコンピューターでtcpソケットを開いていますが、サーバーからそのコンピューターにRTTを取得する方法がわかりません。
これを達成する方法について何かアイデアはありますか?
私はゲームサーバーを書いていますが、c#でクライアントコンピューター(ファイアウォールで保護されている場合)にpingを実行する方法が見つからないようです。
ゲームがそれをどのように行っているかについての情報も見つからないようです。クライアントコンピューターでtcpソケットを開いていますが、サーバーからそのコンピューターにRTTを取得する方法がわかりません。
これを達成する方法について何かアイデアはありますか?
保証された通信パスが1つだけの場合(この場合は既存のTCP接続)、ping
ネットワーク通信プロトコルにコマンドを導入するのが最善の選択肢です。クライアント側のネットワークプロトコルコードは、ネットワーク遅延よりもコンピューターの機能に関係する遅延の発生を回避するために、可能な限り短い時間でこのコマンドに反応する必要がありますが、低速のコンピューターは必然的に低速になるため、これはそれほど重要ではありません。ゲームのパフォーマンスが遅くなるため、実効レイテンシが高くなります。
その場合、サーバーはタイムスタンプ値を使用してpingコマンドを送信し、クライアント側はその値をサーバーに繰り返すだけです。サーバーの最後でタイムスタンプが受信され、ラウンドトリップ時間が計算されます。
正確さによっては、タイムスタンプは数バイトで十分な場合があります。精度は数十ミリ秒までしか得られず、ネットワークの負荷に応じて多くの変動があると想定します。適切なオフセット計算を使用すると、ミリ秒の解像度で1分以上の範囲を2バイトのタイムスタンプに取得できます...ほとんどのゲームに十分です。
または、タイムスタンプが添付されていない最小限のpingコマンドを送信し、サーバーでタイムスタンプを追跡することもできます。この場合、サーバーは送信されたping要求のリストを保持し、それらが返されるときに順番に処理する必要があります。失われたコマンドを識別するためだけに、同期が外れないようにするために、おそらく少なくとも1バイトの識別子が必要です。これにより、これがほんの少しだけ便利になります。
または、通信プロトコルで送信されたコマンドパケットにシリアル番号が含まれている場合は、クライアントに常に最後のコマンドパケットのシリアル番号を返すようにします。シリアル番号とタイムスタンプの制限された長さのキューをサーバーに保持し、クライアントが情報を送信するたびにping時間を計算できます。これにより、pingにのみ実際に役立つ可能性がある数バイトのオーバーヘッドが追加されますが、レイテンシコードが基本通信コードに統合され、pingをスケジュールすることなくライブレイテンシの数値が得られます。
TCPオーバーヘッドを削減するためにネットワークプロトコルでコマンドキューを実行している場合は、pingコマンドをキューの先頭にプッシュする方法があることを確認してください。
ここであなたを助けるかもしれない全体のPingクラスがあります。