Links und Funktionen
Sprachumschaltung

Navigationspfad


Inhaltsbereich

netzwerk.py

Python Source icon netzwerk.py — Python Source, 4 KB (4729 bytes)

Dateiinhalt

# UDP-Server
# erhaelt den Port als Kommandozeilenargument geliefert
import socket,sys 				            # Server-/Systemmodul
from threading import Thread
from visual import *

class udpServer(Thread, socket.socket):
    """modelliert UDP-Server, der den PORT als Kommandozeilenargument erhaelt"""
    def __init__(self,port):
        "Konstruktor"
        Thread.__init__(self)
        socket.socket.__init__(self, socket.AF_INET, socket.SOCK_DGRAM)
        self.port=port
        self.clients = []

    def run(self):
        "Starten des Servers"
        try: 						    # versucht ...
            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 client not in self.clients:
                    self.clients.append(client)
                if not daten:                               # kommt ein Leerstring...
                    self.close()                            # ...faehrt der Server herunter                    
                #
                # HIER WERDEN DIE DATEN VERARBEITET: CONTROLLER 
                #
                print ("Server empfaengt: "+daten+" von "+str(client))
                if daten == "nummer?":
                    self.sendto("self.nummer="+str(self.nummer_geben(client)),client)
                else:
                    for r in self.clients:
                        self.sendto(daten,r)# Antwort
        finally:  					    # ... wird AUF JEDEN FALL ausgefuehrt:
            self.close() 				    # Verbindung schliessen

    def nummer_geben(self,client):
        for i in range (len(self.clients)):
            if self.clients[i]==client:
                return i

###############################
            
if __name__ == "__main__":
    try:
        port = int(sys.argv[1])                             # hole Port-Angabe von der Kommandozeile...
    except:
        port = 50000                                        # andernfalls halt den 50000er!
    s = udpServer(port)                                     # Server mit Port instanziieren
    s.run()                                                 # und starten
    # todo: automatisch abschalten via len(clients)<1...

###############################

PORT=50000

class Verbinder(Thread):
    def __init__(self, benutzer, port =PORT):
        Thread.__init__(self)
        self.server = False
        self.benutzer = benutzer
        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("print 'wer hoert mich?'",
                 ('255.255.255.255', port))                 # sende Nachricht 'an alle'
            self.s.settimeout(2)                                    # warte 1/2 Sekunde..
            print (self.s.recvfrom(64)[0])                             # gibt Servermeldung aus
            #ein Problem, wenn timeout einmal gesetzt ist...
            self.s.settimeout(3000)
        except:                                                 # reagiert auf Zeitueberschreitung
            import subprocess                                       # Modul zum Starten von Subprozessen
            print ("Kein Server vorhanden - starte Server")       # Rueckmeldung
#            subprocess.Popen(['python','server_class.py',str(port)])  # Server starten
            subprocess.Popen(['python','netzwerk.py',str(port)])  # Server starten
            self.s.setblocking(1)                                    # nicht-blockierend
            self.s.sendto("print 'hallo'", ('255.255.255.255', port))
            self.server = True
        finally:
            pass
        self.start()
        
    def run(self):
        while True:
            self.empfangen()
        
    def empfangen(self):
        nachricht = self.s.recvfrom(128)[0]
        self.benutzer.empfangen(nachricht)

    def senden(self,nachricht):
        self.s.sendto(nachricht, ('255.255.255.255', self.port))      # versenden der Nachricht an Tupel(IP, PORT)

##########################

class Teilnehmer():
    def __init__(self, port = PORT):
        self.verbinder = Verbinder(self, port)
    def empfangen(self, nachricht):
         #print ("Empfangene Nachricht: "+nachricht)
         exec (nachricht)
    def senden(self,nachricht):
        self.verbinder.senden(nachricht)


Funktionsleiste