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

(注意:到目前为止,我只用一个连接对此进行了测试) 我不太确定是什么原因造成的。我不认为这是线程干扰(因为有时 sendQueue 可能会被多个线程修改),因为我使用了 threading.Lock,并且乱序总是在相同的 order中,只是不是我放置的 order中的数据包。

我怀疑这个问题与我在这个问题开头概述的“网络”循环有关 - 可能是因为有时没有发送数据包,因为它不是用于指定的数据包,并且它正在通过列表,将其按顺序排列...?

你认为是什么问题,我还做错了什么,你会怎么解决?每个套接字的发送队列而不是全局的?

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

解决该问题的一种方法是创建可迭代对象的副本。例如:

>>> 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 回答