[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [pygame] online game?
Kris Schnee schrieb:
...
> One question for others: I'm finding that even though I'm using the
> socket.select function to make sure a socket has data waiting, I can't
> seem to transmit large amounts of data (more than around 5 KB) without
> one side or the other hanging. (I'll have to look at the code more
> closely later to be more specific.) Any suggestions? My goal was to have
> a server part of my program run independently from both the player
> clients and a display client, but this bug seems to force me to develop
> some annoying protocol for things like sending a list of objects.
> "Prepare for N sending rounds on data for N objects..." rather than
> "here's the complete list of objects and their data all at once."
>
Hi Kris,
Sending more than 5 KB works like a charm if you take care of the amount
of data you want to send:
def _receive(self, MSGLEN):
msg = ''
while len(msg) < MSGLEN:
chunk = self.sock.recv(MSGLEN-len(msg))
if chunk == '':
raise RuntimeError, \
"socket connection broken: received " + str(len(msg)) +
" bytes " \
+ "but " + str(MSGLEN) + " bytes were expected"
msg = msg + chunk
return msg
the socket is initalized like this:
self.sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, port))
There is no information concerning the actual size inside the
default-socket-implementation.
Thus you have to add this information to your stream, here comes the
wrapping function:
def receive(self):
size = self._receive(7)
recvsize = int(size.strip())
message = self._receive(recvsize)
return message
receive fetches the 6 byte long field with the message length (+1 byte
for a newline) at the front
Of course you need the corresponding sending functions:
'''send inserts a 6 byte long field with the message length at the
front'''
def send(self, msg):
size = len(msg)
if size > 999999:
raise RuntimeError, "max messagesize is 999999 byte"
sizefield = '{0:6}'.format(size)
totalmessage = sizefield + "\n" + msg
self._send(size + 7, totalmessage)
print("pythonsocket: SEND " + repr(size) + " bytes")
def _send(self, MSGLEN, msg):
totalsent = 0
while totalsent < MSGLEN:
sent = self.sock.send(msg[totalsent:])
if sent == 0:
raise RuntimeError, \
"socket connection broken"
totalsent = totalsent + sent
dont forget
self.sock.close()
in the end.
(the code in this mail is ripped from a class containing a python socket
in self.sock
(import socket is necessary)
With this method data-interchange is only limited by a size of 999999
bytes, but this limit could be increased by an extended sizefield.
Cheers,
Enrico