kleiner TCP-Server mit SocketServer?
Verfasst: Sonntag 17. August 2008, 11:48
Hi, ich bin noch ziemlicher Python Anfänger, ich versuche mich seit knapp 3 Wochen ein wenig einzuarbeiten... als etwas größeres Projekt habe ich mir vorgenommen einen kleinen Server aufzusetzen, der von meinem Client Verbindungen annimmt, und die empfangenen Daten via Queue an ein anderes Modul weitergibt. Da ich mich zu Anfang nicht groß mit irgendwelchen Protokollen ärgern wollte dachte ich mich ich nehme TCP-IP, da ich dort ein wenig Vorkenntnisse durch meinen Cisco-Kurs habe, und ich dachte das es da auch genug Dokumentationen geben sollte.
Um die Kommunikation einfach zu halten sendet mein Cient immer eine Zeile, die dann auch vom Server eingelesen werden und weitergegeben werden soll.
Im Netz habe ich HIER einen minimalen Server gefunden.
Der Sever lief auch von Anfang an. Nachdem ich hier im Forum auch noch darauf aufmerksam gemacht wurde das ich den Server in einem eingenem Thread laufen lassen müsste um paralel mein Hauptprogramm laufen zu lassen konnte ich auch endlich mein kleines Programm vor den Server setzen, das die eigentliche Arbeit machen sollte.
Jetzt wo es ein wenig aufwendiger bei mir werden sollte soll der Server den eingehenden Stream nach einem Label durchsuchen, und das Label mit einem Zusatz an den Client zurücksenden. Auch das läuft soweit. Am besten poste ich hier mal meinen erweiterten minimalen Server:
Zunächst mal vorweg - ich weiss das ich ein wenig lange Variablennamen für die Warteschlangen genommen habe - die sollten wenn der Server fertig ist geändert werden. Auch weiss ich das ich den Server noch nicht sauber beenden kann. Vor allem das initialisieren mit der Methode run gefällt mir persönlich nicht.... ach ja, aber warum soll ich den code in Ordnung bringen, wenn ich nicht weiss ob ich mein Hauptproblem überhaupt lösen kann 
Nun fal fix zu meinem eigentlichen Problem:
Wenn mein Client sich mit dem Server verbindet läuft die Kommunikation wie erwartet ab - das Label in eckigen Klammern wird aus dem eingehendem Datensatz rausgesucht, und mit einem 'ack' versehen an den client zurückgesendet. Versucht der Client aber nachdem er vom Server den Datensatz mit dem 'ack' empfangen hat noch einmal über den selben stream Daten zu senden, dann versucht er dies vergebens. Der Server akzeptiert über den Stream keine Daten mehr. Das einzige was mir bleibt ist für jede Clientanfrage einen neuen Stream auf einem neuen Port zu erstellen. Da ich mittlerweile alle 2-5 Sekunden eine Serveranfrage generiere sieht das schon ganz interessant aus. Auch habe ich beim programmieren des Client leichte Probleme da ich andauernd einen neuen Stream generieren muss.
Wie erstelle ich einen Server, der den Stream offen hält, und weitere Kommunikation über diesen unterstützt? Muss ich einen völlig anderen Server benutzen, oder kann man meine kleine Variante dahin ausbauen? Und vor allem woran liegt es denn das ich keine Daten mehr empfange? Ich vermute das hat etwas damit zu tun, das der eigentliche Server auf port 9999 wartet und nur von dort Berbindungen entgegennimmt. Aber momentan bin ich etwas überfragt
Schon einmal danke an alle die bis hier hin mit dem lesen gekommen sind
mfg
Sebastian
Um die Kommunikation einfach zu halten sendet mein Cient immer eine Zeile, die dann auch vom Server eingelesen werden und weitergegeben werden soll.
Im Netz habe ich HIER einen minimalen Server gefunden.
Der Sever lief auch von Anfang an. Nachdem ich hier im Forum auch noch darauf aufmerksam gemacht wurde das ich den Server in einem eingenem Thread laufen lassen müsste um paralel mein Hauptprogramm laufen zu lassen konnte ich auch endlich mein kleines Programm vor den Server setzen, das die eigentliche Arbeit machen sollte.
Jetzt wo es ein wenig aufwendiger bei mir werden sollte soll der Server den eingehenden Stream nach einem Label durchsuchen, und das Label mit einem Zusatz an den Client zurücksenden. Auch das läuft soweit. Am besten poste ich hier mal meinen erweiterten minimalen Server:
Code: Alles auswählen
import SocketServer
from threading import *
import Queue
PORT = 9999
class Service(SocketServer.StreamRequestHandler):
#queue wird nach erzeugen der Klasse als Varianble 'WarteschlangeRaus' angef�gt
def ParseLabel(self, daten):
"""Das Label Heraussuchen, mit dem Hinweis ack versehen
und als String zur Empfangsbestätigung zurückgeben"""
Labelende = daten.find("]") +1
Label = daten[:Labelende]
ack = Label +"ack\r\n"
return(ack)
def AufgabeAnClientSenden(self):
"""von P900App ausgehende Aufgaben abarbeiten"""
print"nun sollte die ausgehende Warteschlange abgearbeitet werden"
if self.ServerWarteschlangeAusgehend.empty() == False:
return self.ServerWarteschlangeAusgehend.get()
else:
return "[ClientBored]NONE\r\n"
def handle(self):
"""Eigener TCP- Handler für Serverklasse"""
#auf übertragene Daten warten
data = self.rfile.readline()
#Nachrichtentyp herausfinden und client Accnowledge senden
LabelAcc = self.ParseLabel(data)
if LabelAcc <> "[ClientBored]ack\r\n":
self.wfile.write(LabelAcc)
#daten per queue an die P900App schicken
self.ServerWarteschlangeEingehend.put(data)
#client mit in die Queue schreiben und an die P900App übergeben
client = "[TCPClient]" + self.client_address[0]
self.ServerWarteschlangeEingehend.put(client)
#wenn Clientanfrage nach Aufgaben kam -> nachsehen ob Aufgaben vorhanden sind
else:
ClientAufgabe = self.AufgabeAnClientSenden()
self.wfile.write(ClientAufgabe)
#client in die Queue schreiben und an die P900App übergeben
client = "[TCPClient]" + self.client_address[0]
self.ServerWarteschlangeEingehend.put(client)
class Server(Thread):
"""Serverklasse """
def __init__(self, notify_window, ServerWarteschlangeEingehend, ServerWarteschlangeAusgehend):
"""Init Worker Thread Class."""
Thread.__init__(self)
#Warteschlangen für den Server
self.ServerWarteschlangeEingehend = ServerWarteschlangeEingehend
self.ServerWarteschlangeAusgehend = ServerWarteschlangeAusgehend
#beim initieren gibt es noch keinen dispacher und service
self.dispatcher = None
self.HTTPService = None
#bei schliessen des Main-Threads auch Server beenden
self.setDaemon(True)
self.start()
def run(self):
"""TCPServer auf PORT starten"""
self.HTTPService = Service
#Queue für externe Daten die an die App gehen an den Service weitergeben
self.HTTPService.ServerWarteschlangeEingehend = self.ServerWarteschlangeEingehend
#Queue für interne Daten die an den Client gehen an den Service weitergeben
self.HTTPService.ServerWarteschlangeAusgehend = self.ServerWarteschlangeAusgehend
self.dispatcher = SocketServer.TCPServer(('', PORT), self.HTTPService)
#server starten
self.dispatcher.serve_forever()

Nun fal fix zu meinem eigentlichen Problem:
Wenn mein Client sich mit dem Server verbindet läuft die Kommunikation wie erwartet ab - das Label in eckigen Klammern wird aus dem eingehendem Datensatz rausgesucht, und mit einem 'ack' versehen an den client zurückgesendet. Versucht der Client aber nachdem er vom Server den Datensatz mit dem 'ack' empfangen hat noch einmal über den selben stream Daten zu senden, dann versucht er dies vergebens. Der Server akzeptiert über den Stream keine Daten mehr. Das einzige was mir bleibt ist für jede Clientanfrage einen neuen Stream auf einem neuen Port zu erstellen. Da ich mittlerweile alle 2-5 Sekunden eine Serveranfrage generiere sieht das schon ganz interessant aus. Auch habe ich beim programmieren des Client leichte Probleme da ich andauernd einen neuen Stream generieren muss.
Wie erstelle ich einen Server, der den Stream offen hält, und weitere Kommunikation über diesen unterstützt? Muss ich einen völlig anderen Server benutzen, oder kann man meine kleine Variante dahin ausbauen? Und vor allem woran liegt es denn das ich keine Daten mehr empfange? Ich vermute das hat etwas damit zu tun, das der eigentliche Server auf port 9999 wartet und nur von dort Berbindungen entgegennimmt. Aber momentan bin ich etwas überfragt
Schon einmal danke an alle die bis hier hin mit dem lesen gekommen sind
mfg
Sebastian