The problem I see with this code is that although it is working, some of the information clients(players) send to this server will end up at the method ‘permission’ when intended to end up at ‘clientRequests’, because both of them has recvfrom(). So, if I could specify WHICH addr I want information from as a parameter of recvfrom(), it would solve it. I believe it’s possible with C++, but is it with python, and how?
With TCP this problem doesn’t exist but I prefer UDP.
Something like: recvfrom(512, address=(ip, port)) ?
‘permission’ is used to handle new clients connecting.
The problem would be that information like positions, events sent from a client, will not be taken care of at ‘permission’.
class Server:
def __init__(self):
#host = '192.168.0.2'
host = '127.0.0.1'
port = 50007
addr = (host, port)
self.UDPSock = socket(AF_INET, SOCK_DGRAM)
self.UDPSock.bind(addr)
self.UDPSock.settimeout(5.0)
self.searchForClients = True
self.playersOnline = []
threading.Thread(target=self.permission).start()
Gui.add_event("Server online on port %s" % port)
def permission(self):
global _status
while self.searchForClients:
time.sleep(0.5)
_status.set("Status: Running; Connected: %s" % len(self.playersOnline))
try:
clientMessage, addr = self.UDPSock.recvfrom(1024) # , MSG_PEEK
except:
clientMessage = ""
if clientMessage == "CONNECT" and addr not in self.playersOnline:
if self.searchForClients:
self.addNewClient(addr)
elif clientMessage == "DISCONNECT" and addr in self.playersOnline:
self.removeClient(addr)
Gui.add_event("No longer accepting logins")
return False
def clientRequests(self, addr):
latestRequest = time.time()
while addr in self.playersOnline:
time.sleep(0.01)
try:
data, requestAddr = self.UDPSock.recvfrom(1024)
except:
requestAddr, data = "", ""
if requestAddr == addr:
latestRequest = time.time()
dataCommand = data.split(':')
if time.time() - latestRequest > 2:
if addr in self.playersOnline:
self.removeClient(addr)
if not self.searchForClients:
Gui.add_event("Player %s(%s) forcibly removed" % addr)
return False
I believe that threads unnecessarily complicate simple UDP servers like this one. Just listen on the socket and dispatch the calls based on whether packet’s source address has already been seen.
And no, regular
recvfrom(2)system call does not allow you to “filter” what address you get data from, only to get that information. Filtering is done withconnect(2)on UDP socket, but that limits you to a single source per socket.