C / C ++マルチプレイヤーゲームのネットワークメッセージをシリアル化およびシリアル化解除する最良の方法は何ですか?


11

現在JSONを使用しており、クライアントとサーバー間のメッセージの種類によってはバイナリ形式に移行したいと考えています。

構造体をソケットに読み込むだけですか?プロチコールバッファー/リサイクルを使用しますか?

データの配列をどのように表すべきですか?

データのパック/アンパックのインターフェースはどのように見えるべきですか?

回答:


12

想定しています...

  1. あなたはバイトのバッファに変換することについて話している
  2. UDPを使用していて、パフォーマンスが問題である

構造を定義するためにパケットのスペースを無駄にしないようにしてください。IEは最低でも、パケットのタイプを示すバイトを送信し、受信した各パケットがそのタイプのパケットの事前定義された構造に従うと仮定します

構造体をソケットに読み込むだけですか?プロチコールバッファー/リサイクルを使用しますか?

  • はい、構造体全体が必要な場合は、構造体全体をお読みください
  • いいえ、パケット構造を自分で作成します。これは、これらの方法を使用したシリアル化よりも確実に小さくなります。パケットに含めるデータを正確に把握する必要があります

データの配列をどのように表すべきですか?

  • データの配列として。受信すると、配列の要素のカウントの送信を回避するために、データの終わりまでバッファーの読み取りを継続します

データのパック/アンパックのインターフェースはどのように見えるべきですか?

  • 基本的な型をバイトに変換する一連のメソッドを簡単にセットアップできます。そこから、これらのメソッドに基づいてカスタム型も変換できます。これを行う方法の詳細は、確信しているほぼどこでも見つけることができます(私は個人的にC#を使用しています)

最後に、パケットサイズ特にスナップショットの場合に問題になります。サイズ= packetSize xエンティティx connectedPlayers; したがって、パケットごとに60 x 10 x 16 = 9,600バイトになる可能性があります。次に、これを1秒に20回送信します。= 192,000 bps = 187 KBps。これは明らかに帯域幅の高いアップロード速度です。したがって、可能であれば、パケットサイズに寄与する各要素を最小限に抑える必要があります。

この記事は私を大いに助けてくれました: Valveマルチプレイヤーネットワーキング


さまざまなオブジェクトのシリアル化を読み取り、ここで質問をネットワーキングしながら、私が発見したことを別の記事では、数週間前だったこの1 Unrealのエンジンがそれをしない方法を説明します。バルブソースの比較の良い点。
マーティンフット

1
あなたの配列メソッドは一般的なケースでは機能しません-「データの終わり」はどこですか?メッセージが区切られている場合でも、構造体ごとに1つ以上の配列を持つことはできません。これを修正するには、元のポスターが固定長の配列に固執するか、構造体ごとに(構造体の最後に)配列が1つだけであることを確認するか、配列の最初にカウント値を送信します。
カイロタン2011

もう1つのヒント:エンディアンを治療することを忘れないでください。そのようなことが存在することを知らなければ、これは非常に煩わしいものになる可能性があります。

良い点@Kylotan、特定のケースではこの余分なデータは避けられないことに同意します。しかし、私は自分自身を単一のパケットに複数のアレイを追加見つけた場合、私の代わりに複数のパケットを送信して検討する
indeed005

1

この問題はGoogleとFacebookによって解決されています。

  1. Googleのプロトコルバッファ — GoogleはC ++の大ユーザーです。

    プロトコルバッファは、構造化データを効率的かつ拡張可能な形式でエンコードする方法です。Googleでは、ほとんどすべての内部RPCプロトコルとファイル形式にプロトコルバッファーを使用しています。

  2. Apache Thrift(以前はFacebookによる):

    Thriftは、スケーラブルな言語間サービス開発のためのソフトウェアフレームワークです。ソフトウェアスタックとコード生成エンジンを組み合わせて、C ++、Java、Python、PHP、Ruby、Erlang、Perl、Haskell、C#、Cocoa、JavaScript、Node.js、Smalltalk、OCamlの間で効率的かつシームレスに機能するサービスを構築します。


Googleのプロトコルバッファは、大規模なリアルタイムゲームには遅すぎます。ただし、バージョン管理のため、プロトタイピングやプレーヤーの数を減らすには非常に適しています。いつものように、プロファイラーが実際のストーリーを伝えます。
Patrick Hughes

まあ、それらはグーグルにとって十分に良いです、そしてグーグルはかなりよくスケーリングします、そして私がそれらを使ったとき彼らはうまく働きました。それが私が彼らを推薦した理由です。
有料オタク2011

Googleはリアルタイムのパフォーマンスを必要としません。Googleは信頼性と稼働時間を必要としますが、どちらもプロトコルバッファによって適切に処理されます。これらすべてのフォールバックバージョニングとボイラープレートコード生成の複雑さはオーバーヘッドを追加し、50〜100ミリ秒の間隔で1000の更新を送受信している場合は、追加されます。手元のデータに固有のコード化されたシリアライザに対して、古いバージョンのプロトコルバッファをプロファイリングします。@ indeed005には要旨があります。
Patrick Hughes

+1、これらの形式はほとんどのリアルタイムまたは高帯域幅のゲームには少し大きすぎて遅いですが(任意の複雑なパケットを再構築できる追加情報が含まれているため)、これはそれらがいくつかのゲーム、例えば。ターンベースのもの。すべてのリソースを最適化する必要がない場合、これらの形式は多くの時間を節約でき、JSONよりも効率的です。
カイロタン2009
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.