stickman_network.py
stickman_network.py — Python Source, 4 KB (5026 bytes)
Dateiinhalt
import socket,sys from threading import Thread from visual import * PORT=55155 if sys.version_info.major < 3: PYTHON_NEW = False else: PYTHON_NEW = True class udpServer(Thread, socket.socket): def __init__(self,port): Thread.__init__(self) socket.socket.__init__(self, socket.AF_INET, socket.SOCK_DGRAM) self.port=port self.clients = [] self.V = [] for i in range(0,60): if random.randint(0,50) < 25: self.V.append(random.randint(-225,-25)) else: self.V.append(random.randint(25,225)) def run(self): try: self.bind(("",self.port)) # alle IP-Adressen auf Client-PORT while True: # laeuft solange bis Tastaturabbruch daten, client = self.recvfrom(256) # holt Daten und Adresstupel von Bindung if PYTHON_NEW: daten = str(daten,'UTF-8') if client not in self.clients: for player in self.clients: self.senden_an("players.append(Man(pos=(0,0,0)))",client) self.clients.append(client) nummer = self.clients.index(client) self.senden_an("generate("+str(self.V)+")",client) self.senden_an("self.nummer="+str(nummer),client) self.senden_an_alle(str(daten)) elif not daten: # kommt ein Leerstring... break # wird Schleife beendet elif daten == "!ende": # Signal zum Schliessen des Servers self.senden_an_alle("!ende") break # Schleife beenden else: self.senden_an_alle(daten) except: print sys.exc_info()[0] print ("Problem: Server laeuft nicht.") finally: print ("\nServer schliesst sich jetzt.") self.close() # Verbindung schliessen def senden_an_alle(self,nachricht): for r in self.clients: self.senden_an(nachricht,r) def senden_an(self, nachricht, empfaenger): if PYTHON_NEW: nachricht = bytes(nachricht,'UTF-8') self.sendto(nachricht,empfaenger) class udpClientPlus(Thread): """Legt einen Client an. Der sendet einen Broadcast, wenn der von einem Server empfangen wird, wird der Empfang bestaetigt und der Client am Server registriert. Wenn es keine Antwort eines Servers gibt, wird ein Server als Thread angelegt.""" def __init__(self, benutzer, pos, port = PORT, new = PYTHON_NEW): Thread.__init__(self) self.benutzer = benutzer #an diesen wird Nachricht weitergeleitet self.port = port self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # AF_INET = IPv4, SOCK_DGRAM = UDP self.s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1) # Broadcast ermoeglichen #Testen, ob es schon einen Server gibt try: self.s.sendto("players.append(Man(pos=(0,0,0)))", ('255.255.255.255', port)) # sende Nachricht 'an alle' - in ausfuehrbarer Form, falls exec(nachricht), wird aber eh ignoriert self.s.settimeout(2) # warte ein bisschen.. nachricht = self.s.recvfrom(64)[0] if PYTHON_NEW: nachricht = str(nachricht,'UTF-8') self.s.settimeout(3000) except: # reagiert auf Zeitueberschreitung print ("Kein Server vorhanden - starte Server") # Rueckmeldung server = udpServer(port) # Starten eines Servs als Thread server.start() self.s.setblocking(1) # nicht-blockierend #dem server etwas Zeit lassen, damit er Anmeldung verarbeiten kann from time import sleep sleep(5) #Erstanmeldung am (jetzt) laufenden Server self.senden(str("players.append(Man(pos=(0,0,0)))")) self.start() def run(self): "Hier lauscht der Client auf Nachrichten und leitet sie an den eigentlichen Benutzer weiter." while True: nachricht = self.s.recvfrom(512)[0] if PYTHON_NEW: nachricht = str(nachricht,'UTF-8') if nachricht == "!ende": print ("\nClient beendet.") break self.benutzer.empfangen(nachricht) def senden(self,nachricht): "Diese Methode nutzt der eigentliche Benutzer, um Nachrichten an den Server verschicken." if PYTHON_NEW: nachricht = bytes(nachricht,'UTF-8') self.s.sendto(nachricht, ('255.255.255.255', self.port))