I've finally got some time to spend on building something useful for pygame networking.
I've had a look at the latest Twisted (2.5), and it seems that there is no longer any support for integrating the twisted event loop with pygame. Bah. Anyhow, I figure there is enough brains on this list for us to nut something out, which is simple, and works on a variety of platforms. So... if anyone is interested in helping out, please throw your 2c in. I've attached my first thoughts in two .py files. interface.py contains basic UDP class, and also contains classes specific for each platform. (At this stage I'm not interested in dealing with TCP connections) pygnet.py contains a class for detecting missing packets in a sequence, on a channel. My idea is to build up layers of reliability using class inheritance, so you can pick the class you need for the type of data you want to send... Once all this low-level stuff is done, we could add lobby systems, score systems etc which are fairly generic and easily used across different games/apps. Anyone interested? -- :: Simon Wittber :: http://www.linkedin.com/in/simonwittber :: phone: +61.4.0135.0685 :: jabber/msn: [EMAIL PROTECTED]
from socket import socket, AF_INET, SOCK_DGRAM, error import sys MAX_PACKET_SIZE = 1024 class BaseUDPInterface(object): def __init__(self, address): self.socket = socket(AF_INET, SOCK_DGRAM) self.socket.bind(address) self.socket.setblocking(0) def handle_error(self, e): pass def handle_recv(self, address, packet): pass def poll(self): try: packet, address = self.socket.recvfrom(MAX_PACKET_SIZE) except error, e: self.handle_error(e) else: self.handle_recv(address, packet) def send(self, address, packet): try: self.socket.sendto(packet, address) except error, e: self.handle_error(e) if sys.platform[:5] == 'linux': class UDPInterface(BaseUDPInterface): def handle_error(self, e): pass elif sys.platform[:3] == 'win': class UDPInterface(BaseUDPInterface): def handle_error(self, e): pass
import struct from interface import UDPInterface class UnreliableInterface(UDPInterface): def __init__(self, *args, **kw): UDPInterface.__init__(self, *args, **kw) self.outbound_channels = {} self.inbound_channels = {} def dispatch(self, channel, address, data): pass def send(self, address, channel, data): seq_id = self.outbound_channels.get(channel, 0) self.outbound_channels[channel] = seq_id + 1 packet = struct.pack("!ii", channel, seq_id) + data UDPInterface.send(self, address, packet) def handle_missing(self, recieved_id, expected_id): pass def handle_recv(self, address, data): channel, seq_id = struct.unpack("!ii", data[:8]) expected_seq_id = self.inbound_channels.get(channel, 0) if seq_id != expected_seq_id: self.handle_missing(seq_id, expected_seq_id) self.inbound_channels[channel] = seq_id + 1 data = data[8:] self.dispatch(channel, address, data) class ReliableInterface(UnreliableInterface): """ This class needs to track sent packets, handle resend conditions etc. """ pass if __name__ == "__main__": s = UnreliableInterface(('127.0.0.1',1999)) c = UnreliableInterface(('127.0.0.1',1992)) for i in xrange(1000): s.send(('127.0.0.1',1992), 0, 'blah'*1000) s.poll() c.poll()