我正在使用Python后端服务器开发多人Flash游戏,而且我在服务器上遇到了一些问题。
我正在为服务器使用异步TCP套接字(使用select
),我还维护一个“发送队列”,其中数据包按照调度的顺序排队,然后在{{{{ 1}}告诉我套接字是可写的。
基本上,它的结构如下:
(注意:每个“数据包”都有一个相关的套接字)
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")
(注意:到目前为止,我只用一个连接测试了这个) 我不太确定是什么原因造成的。我不认为这是线程干扰(因为有时sendQueue可能被多个线程修改)因为我使用了threading.Lock,并且乱序总是以相同的顺序,只是不按我把数据包放入的顺序。
我怀疑这个问题与我在这个问题开始时概述的“网络”循环有关 - 也许是因为有时候数据包不会发送,因为它不是用于指定的数据包,而是在列表中添加漏洞,将其推迟排序......?
你认为问题是什么,我还有什么不对,你会如何解决?每个套接字而不是全局套接字的发送队列?
答案 0 :(得分:2)
基于伪代码,您似乎在迭代它时修改队列。那可能很危险。例如:
>>> x = range(10)
>>> for i in x:
... print i
... if i%2==0:
... x.remove(i)
...
0
2
4
6
8
解决该问题的一种方法是创建iterable的副本。例如:
>>> 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