3

私はソケット サーバーとフラッシュ ゲーム クライアントを書いています。このゲームでは、移動や回転などのリアルタイム コマンドが必要です。これらのコマンドがサーバーからクライアントにできるだけ早く送信されることが重要です。そうしないと、他のクライアントが移動/向きを変えるクライアントとの同期が大幅に失われるためです。

これは、ネーグル算術によって引き起こされる問題の例です。

: これらのコマンドの意味を理解したい場合は、以下のコマンド表を参照してください。

最初のものは私が動かした船です(前進+右、前進は受信されましたが、右ではありません)

コマンドを送信するクライアント:

84796: Sending data: 2#4
84796: Sending data: 2#2
84904: Sending data: 2#3
84904: Sending data: 2#0
86187: Sending data: 2#4
86188: Sending data: 2#2
86374: Sending data: 2#3
86404: Sending data: 2#0

コマンドを受信するクライアント:

79244: Raw receive: 3#3#4$
79244: New command: 3#3#4
79398: Raw receive: 3#3#2$3#3#3$3#3#0$
79399: New command: 3#3#2
79399: New command: 3#3#3
79399: New command: 3#3#0
80635: Raw receive: 3#3#4$
80635: New command: 3#3#4
80908: Raw receive: 3#3#2$3#3#3$3#3#0$
80908: New command: 3#3#2
80908: New command: 3#3#3
80908: New command: 3#3#0

「瞬間」は私が言おうとしていることを意味しない奇妙な用語ですが、ここでは前のコマンドからのミリ秒単位の時間のようです

  1. クライアント A が送信 (瞬間: 0)、クライアント B が受信 (瞬間: 0)

  2. 右折 クライアント A が送信 (瞬間: 0)、クライアント B が受信 (瞬間: 155)

  3. クライアントAによる送信の停止(瞬間:108)、クライアントBによる受信(瞬間:0)

  4. クライアントAが送信を停止する(瞬間:0)、クライアントBが受信する(瞬間:0)

  5. クライアント A によって送信された転送 (瞬間: 1283)、クライアント B によって受信された (瞬間: 1236)

  6. 右折 クライアント A が送信 (瞬間: 1)、クライアント B が受信 (瞬間: 273)

  7. クライアント A が送信した動きの停止 (瞬間: 186)、クライアント B が受信した (瞬間: 0)

  8. クライアント A による送信の回転を停止 (瞬間: 30)、クライアント B によって受信 (瞬間: 0)

これは、コマンドに対応するコマンド テーブルです。

クライアント -> サーバー

2# (movement info)
0) now not turning
1) now turning left
2) now turning right
3) now not moving
4) now moving forward

サーバー -> クライアント

3# (movement info)
[shipId]#
0) now not turning
1) now turning left
2) now turning right
3) now not moving
4) now moving forward

つまり、"Nagle" のためにコマンドが完全に非同期になっていることがわかります。これにより、移動停止コマンドが移動開始コマンドと同時に他のクライアントによって受信され、そのプレイヤーはまったく移動しなくなります。

これが、これらのコマンドを TCP サーバーによって可能な限り高速にリアルタイムで送信する必要がある理由です。簡単な修正方法は、単に Nagle を無効にすることです。しかし、私はググってみました (tcp メッセージのパーシャルに関する彼の提案は私のシステムに実装されていますが、タイミングとは何の関係もないことに注意してください)。

この原因に対して Nagle アルゴリズムを無効にするべきではなく、代わりに他の解決策を探すべきであるというのは本当ですか? なぜだめですか)?

前もって感謝します。- トム

4

5 に答える 5

5

TCP_NODELAY を使用して、そのソケットの nagle アルゴリズムをオフにします。最新のOSにはシステム全体で無効にする設定があり、それは眉をひそめていますが、低遅延が必要であることがわかっているソケットでそれを行うべきではない理由はありません.

setsockopt(TCP_NODELAY)

于 2009-10-22T21:08:13.027 に答える
1

スイッチ、ルーター、ISPのswithcgear ....などもすべて、黒い小さな内臓をくすぐる可能性があることに注意してください。汚い小さな獣はパケットを読むことができるので、彼らは自由を取り、時々それらを書き直します。

よりネットワークで存続可能なアプローチについては、RTP(UDP上で実行される)を参照してください。

于 2009-10-22T21:15:00.437 に答える
1

Windows は遅延 ACKと Nagle を実装していることに注意してください。これにより、個々の TCP メッセージでさらに 200 ミリ秒の遅延が発生する可能性があります。私の知る限り、レジストリ キー (場合によってはレジストリ キーを有効にするためのホットパッチ) を使用しない限り、Windows でこれを変更することはできません。

于 2009-11-01T13:55:34.643 に答える
1

船が全員の画面で同じことをするようにすることが目標である場合は、位置の更新を送信する必要があります。クライアントAが次のことをしたからといって、それを想定することはできません:

  • 左折してください
  • 100ミリ秒待つ
  • 回すのをやめる

そのクライアント B では、まったく同じ 100 ミリ秒の遅延が発生します。Nagle バッファリングはこれをより極端にしますが、常にジッターとさまざまな遅延が発生します。

あなたは本当に次のようなものを送る必要があります:

  • (私は位置 X1、Y1、見出し Z1 にいます) 左に曲がる
  • (私は位置 X2、Y2、見出し Z2 にいます) 回転を停止します

クライアントが継続的に再同期するようにします。

于 2009-10-22T23:04:47.300 に答える