I'm working on a simple multiplayer online text game and I read select()
and poll()
were popular methods for multiplexing I/O.
I found this example in the GNU C docs, which uses select
. I ran it and made 3 Python test clients that look like this:
import socket
import time
port = 5555
test = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
test.connect(('localhost', port))
while 1:
test.send('aaaa')
time.sleep(0.5)
Then I ran the clients (from the same computer that's running the server) with different strings (aaaa
, 55
and ..
).
The output of the server was
Server: got message: `aaaa'
Server: got message: `55aa'
Server: got message: `aaaa'
Server: got message: `55aa'
Server: got message: `..aa'
The strings were getting mixed up.
Is this some kind of silly compilation error, an error in my test clients or the fact that I'm running clients and servers from the same computer? Or is this program telling me I shouldn't use select
for this purpose? Considering that I'll use this for a multiplayer game server (which probably gets lots of messages per second), I don't think I can let the messages get mixed up.
The clients and server are completely asynchronous. You don't know which is going to get time on the CPU and in which order. The network also provides no guarantee about order of delivery (though TCP will ensure that the application sees data from a single client in the order it was sent).
Select/poll return a list of sockets that have data to read. Make sure you read them all before calling select/poll again otherwise you will be prioritizing connections on lower-numbered ports.
Note that a read is raw data, not terminated in any way, and so cannot be dumped directly as a string unless the sender included a NUL terminator in the write to its socket.