简体   繁体   中英

Why is my list out of order consistently?

I'm working on a multiplayer Flash game with a Python backend server, and I'm having some issues with the server.

I'm using async TCP sockets for the server (using select ), and I also maintain a "sending queue" where packets are queued in the order that they are dispatched, and are then sent when select tells me that the socket is writable.

Basically, it is structured like this:

(note: every "packet" has an associated socket)

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

Upon first look, this seems fine for me, but it seems that my sending queue is out of order .

It always seems to be in the same order, but not the right order. For example, the server sends some Chat packets to the client to introduce them to the server. I do that like this:

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")

However, it always arrives in this order:

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

(note: I've only tested this with one connection so far) I'm not quite sure what's causing this. I don't think it's thread interference (as sometimes sendingQueue might be modified by more than one thread) because I use a threading.Lock, and the out-of-orderness is always in the same order , just not in the order I put the packets in.

I have a suspicion this issue has something to do with my "networking" loop that I outlined at the start of this question - perhaps because sometimes the packet is not sent because it is not intended for the specified packet, and it is putting holes through the list, pushing it out of order...?

What do you think is the problem, what else am I doing wrong, how would you solve it? A sending queue for every socket rather than a global one?

Based on the pseudocode, you appear to be modifying the queue while iterating over it. That can be dangerous. For example:

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

One approach to get around that issue is to create a copy of the iterable. For example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM