Hilfe zu asynchat und asyncore

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
amarganth
User
Beiträge: 8
Registriert: Dienstag 10. August 2004, 12:24
Wohnort: Bern

Hi Python-Cracks

Ich arbeite seit kurzer Zeit mit Python, finde diese Sprache aber immer besser. :lol: Trotzdem komme ich in einem bestimmten Punkt nicht weiter und bitte um Hilfe. :?:

Ich arbeite an einem Programm, das zwei Verbindungen machen will:
- eine Telnetverbindung ins Internet auf einem bestimmten Port
- eine Telnetverbindung lokal (localhost)

Ich habe eine Lösung, die läuft, aber sehr unschön: Ich arbeite mit der Telnetlib und einem Timer und frage so 5x pro Sekunde ab, ob Daten kommen. Hässlich. Noch hässlicher: Die Verbindung läuft zeilenorientiert und ich buffere selber.

Nun fand ich die Bibliotheken asyncore und asynchat. :idea: Und set_terminator! :shock: Tönt vielversprechend. Leider sehe ich in der Onlinehilfe nur ein Beispiel eines HTTP-Servers. Das ist nicht, was ich brauchen kann. Und ich bin nicht in der Lage, den Code entsprechend meinen Bedürfnissen anzupassen. :oops:

Kann mir jemand bitte helfen, diese Library für einen Client zu verwenden? Mit nota bene zwei parallelen Verbindungen? :roll: :oops:

Allerherzlichsten Dank im voraus.

amarganth
Sorgenkind
User
Beiträge: 34
Registriert: Samstag 24. Juli 2004, 19:25
Kontaktdaten:

hmm
...

Code: Alles auswählen

import asnycore,asynchat,socket

class verbindung(asynchat.async_chat):
    def __init__(self,server,port=23):
        asynchat.async_chat.__init__(self)
        self.set_terminator("\n")
        self.create_socket(socket.AF_INET,socket.SOCK_STREAM)
        self.connect((server,port))
    def handle_connect(self):
        #irgendwas beim verbinden senden vll? zb anmelden

    def found_terminator(self):
        zeile=self.ac_in_buffer #das wäre eine zeile die vom server kommt
        #was mit der zeile machen...

    def collect_incoming_data(self,data):
        return #brauchen wir hier nicht...

    def send_line(self,line):
        """Sendet eine Zeile an den server"""
        self.push(line+"\n")

conn1=verbindung("localhost")
conn2=verbindung("andererserver")

asyncore.loop()
so könnte das aussehen?
amarganth
User
Beiträge: 8
Registriert: Dienstag 10. August 2004, 12:24
Wohnort: Bern

Eigentlich ist es ja ganz einfach, wenn man weiss, wie die Funktionen in der Hilfebeschreibung zu verwenden sind. :shock:

Allerbesten Dank, Sorgenkind, Du hast mir sehr geholfen. Es klappt! :lol:

Nur, wie kann es anders sein, hat sich das Problem jetzt verschoben.
Als Gui verwende ich wxWindows / wxApp / wxFrame. Nun beissen sich aber die beiden Endlosschlaufen:

Code: Alles auswählen

asyncore.loop()
und

Code: Alles auswählen

app.MainLoop()
Hmm. Wie komme ich aus diesem Schlamassel raus?
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Musst halt asyncore.loop() in einen Thread packen.

Gruss
Sorgenkind
User
Beiträge: 34
Registriert: Samstag 24. Juli 2004, 19:25
Kontaktdaten:

die gui mainloop in nen thread ist besser denk ich weil die weniger auslastung braucht...

einfach:

Code: Alles auswählen

import thread
thread.start_new(app.MainLoop,())
Das is das einfachste...
aber threadfreie lösungen gäbe es auch... wxTimer könntest du dir mal anschaun und mit dieser funktion kombinieren:

Code: Alles auswählen

def loop_once(timeout=0.5):
    if asyncore.socket_map:
        asyncore.poll(timeout,asyncore.socket_map)
    else:
        time.sleep(timeout)
(in python 2.4 wäre es einfach asyncore.loop(count=1))
amarganth
User
Beiträge: 8
Registriert: Dienstag 10. August 2004, 12:24
Wohnort: Bern

Hi Sorgenkind, rayo und alle anderen, die an diesem Thema interessiert sind

Besten Dank fuer die Loesung. Ich habe jetzt einen Thread gebastelt, der mir die beiden Verbindungen bearbeitet. Klappt soweit wunderbar. Ich habe nicht das GUI als Thread gestartet, weil ich denke, das Gui hat mehr zu tun (Datenaufbereitung). Aber das werde ich später noch untersuchen.

Also:
- ich habe einen Thread, der die beiden Verbindungsklasse abhorcht
- ich möchte die erhaltenen Zeilen im Gui (wxFrame) verarbeiten

Nur:
Ich finde jetzt keine passende Lösung, um beim Erhalt einer Zeile aus einer Verbindungsinstanz die Daten in der Klasse wxFrame zu verarbeiten. Ich möchte die beiden Klassen auch nicht verbinden ("Multiple Inheritance"). Selbstverständlich könnte ich mittels eines Timers aus wxFrame die Zeilen abholen. Aber das erscheint mir hässlich. Ist eine Callbackfunktion die Lösung?

Danke schon jetzt für etwaige Lösungsansätze!
amarganth
User
Beiträge: 8
Registriert: Dienstag 10. August 2004, 12:24
Wohnort: Bern

ENTWARNUNG:

Ich habe ein Beispiel in der Literatur gefunden. Und umgesetzt. Es klappt.

Danke mal ganz schön allen, die bei der Lösungsfindung mitgeholfen haben.

:oops: :idea:
Antworten