0

Pythonバックエンドサーバーを使用してマルチプレイヤーFlashゲームに取り組んでいますが、サーバーに問題があります。

サーバーに非同期TCPソケットを使用しています(を使用select)。また、パケットがディスパッチされた順序でキューに入れられselect、ソケットが書き込み可能であると通知されたときに送信される「送信キュー」を維持しています。

基本的に、次のように構成されています。

(注:すべての「パケット」には関連するソケットがあります)

every 'networking' loop:
    acquire sending queue mutex

    for every writable socket acquired with select():
        for every packet in the sending queue:
            if this packet is intended to be sent with this writable socket:
                send the packet
                remove the packet from the sending queue

    release sending queue mutex

一見すると、これは私には問題ないように見えますが、送信キューが故障しているようです。

常に同じ順序になっているように見えますが、正しい順序ではありません。たとえば、サーバーはいくつかのChatパケットをクライアントに送信して、それらをサーバーに導入します。私はこのようにします:

player.sendMessage("Welcome to Nanoxide's public server, " + player.getName() + "!")
player.sendMessage("The server is version " + self.getServer().getVersion())
player.sendMessage("and it is running under " + str(int(psutil.cpu_percent())) + "% CPU load.")
player.sendMessage("")

self.getServer().broadcastMessage(player.getName() + " joined the game")

ただし、常に次の順序で到着します。

This server is version <version>
<blank line>
Welcome to Nanoxide's public server, <playername>!
<playername> joined the game

(注:これまでのところ、1つの接続でのみテストしました)これ を引き起こしている原因はよくわかりません。私はthreading.Lockを使用しているので、スレッドの干渉ではないと思います(sendingQueueが複数のスレッドによって変更される場合があるため。のパケット。

この問題は、この質問の冒頭で概説した「ネットワーキング」ループに関係しているのではないかと疑っています。おそらく、指定されたパケットを対象としていないためにパケットが送信されず、穴が開いているためです。リスト、それを順不同に押し出す...?

問題は何だと思いますか、他に何が間違っているのですか、どのように解決しますか?グローバルソケットではなく、すべてのソケットの送信キュー?

4

1 に答える 1

2

擬似コードに基づいて、キューを反復処理しているときにキューを変更しているように見えます。それは危険かもしれません。例えば:

>>> x = range(10)
>>> for i in x:
...     print i
...     if i%2==0:
...             x.remove(i)
... 
0
2
4
6
8

この問題を回避するための1つのアプローチは、反復可能ファイルのコピーを作成することです。例えば:

>>> x = range(10)
>>> for i in x[:]:
...     print i
...     if i%2==0:
...             x.remove(i)
... 
0
1
2
3
4
5
6
7
8
9
于 2013-03-19T02:24:17.990 に答える