ネットワーク その3 帯域

ネットワーク帯域とは、どれだけの量のデータを送受信できるかを表します。データ量が上限に近づくほどにパケットロスの量が増え、この上限を超えたデータ量を送ろうとした場合、結果的にセッションから切断されることになってしまいます。

XNA Frameworkでは帯域をバイト/秒で表します。まぎらわしいことにネットワークベンダーはビット/秒で表すのが好きで(多分、より数字を大きく見せるため)、さらにまぎらわしいことにどちらの表記もbpsやkbpsを使うことです。この表記が出てきた場合にはバイト/秒なのかビット/秒のどちらのことを表しているのか注意する必要があります。(訳注:私は個人的にバイト/秒は大文字のB/s、ビット/秒はをbit/sと区別して表記するようにしています)

 

より多くのユーザーに遊んで貰うために色々な家庭のインターネット接続を考慮してXboxのゲームでは最小で上り、下り8KB/sの帯域で動作することが求められます。

ネットワーク帯域と言うと、ゲーム内で送受信するデータ量x接続するマシン数と考えがちですが、ここで忘れてはいけないのはデータパケットのヘッダー部分のサイズです。

  • 20バイトのIPヘッダー
  • 8バイトのUDPヘッダー
  • ~22バイトのLIVEやXNA Frameworkで使われる部分(NAT Traversal、暗号化、Reliable/Ordered転送用の情報)

これで~50バイトのパケットヘッダーサイズになります。

例えばプレーヤー毎にBoolean値を、60フレーム/秒の間隔で転送すると:

  • 1バイトのペイロードデータ
  • +50バイトのヘッダー = 51バイト
  • *60パケット/秒 = 3060バイト

ホァ!Boolean値一個のデータ転送だけでも3KB/sになってしまいます(ゴールは8KB/sということを思い出してください)。98%の帯域がパケットヘッダーで無駄に消費されてしまいます。

 

では、どうやってこの厄介なヘッダー問題を回避することができるのでしょうか?

  • データ転送頻度を下げる
    • 通常のゲームでは毎フレーム毎にパケットを送るのではなく、1秒間に10~20パケットの割合で送っています
    • この転送頻度は動的に変化させることができます。例えば遠くのプレイヤーにはより低頻度でパケットを送ります
    • MotoGPではXbox LIVE上で最大16人同時プレイができます。これだけの人数になると1秒間に4パケットが上限でした。この為により効果的な予測アルゴリズムを使って低レートでも滑らかに動作させる必要がありました。
  • パケットをまとめる
    • 沢山の小さいパケットを1つの大きなパケットにすることで、パケットヘッダーのサイズの無駄を少なくすることができます。
    • 通知メッセージを即座に送るのではなく、複数のフレームを待たせることによってパケットをまとめる
    • もし同じフレーム内で複数のパケットを同じ相手に送った場合、次にNetworkSession.Updateを呼んだときに自動的まとめてくれます。
    • XNA Frameworkは自動的にボイスデータやrealiable UDPの確認などを既にあるパケットにまとめるので、これらのデータは独立したヘッダーを必要としません。

 

原文
http://blogs.msdn.com/shawnhar/archive/2007/12/18/network-bandwidth-packet-headers.aspx