Links und Funktionen
Sprachumschaltung

Navigationspfad
Sie sind hier: Startseite / Probestudium / 2015 / WS I: 3D-Programmierung / Arbeitsgruppen 3D-Python / Stickman / stickman_network.py


Inhaltsbereich

stickman_network.py

Python Source icon 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))




Funktionsleiste