Reverse http bzw. Reverse Proxy

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Klappstuhl
User
Beiträge: 11
Registriert: Dienstag 5. Januar 2010, 13:55

Hi allerseits,

ich beiße mir an einem Problem schon etwas länger die Zähne aus. Vielleicht kann mir ja einer von euch bei diesem Problem helfen?!

Folgende Aufgabenstellung:
Ich muss mich als Client zu einem Server verbinden. Diesem schicke ich über einen Socket eine bestimmte Zeichenfolge und der Server antwortet mit einer bestimmten Zeichenfolge. Soweit so gut.
Ist die Zeichenfolge der Antwort korrekt, sollen die beiden die gleiche (!) Verbindung benutzen, jedoch die Rollen tauschen. D.h. der frühere Client wartet jetzt immer auf Anfragen von dem früheren Server.

Ich hoffe, das Problem jetzt sinnvoll erklärt zu haben. Es wird also einmalig eine Verbindung aufgebaut und diese soll dauerhaft verwendet werden.

Verwende ich nun für den Client die üblichen Funktionen (zuerst create_socket, dann connect, dann send), wird die Verbindung nach der Antwort ja geschlossen. Starte ich den Socket als Server (create_socket, bind, listen...), kann ich ja nicht die initiale Nachricht schicken (zumindest führt der Aufruf socket.sendto(msg, addr) zu einem Fehler.

Kann mir jemand sagen, wie man in einer bestehenden Verbindung die Rollen tauschen kann? Ich verwende derzeit Python 2.6.7., falls das relevant ist.

Vielen Dank schon mal!
BlackJack

@Klappstuhl: Wieso wird beim Client die Verbindung geschlossen? Das passiert nur wenn auf einer der beiden Seiten die Verbindung geschlossen wird. Wird sie das nicht, bleibt sie offen.
Klappstuhl
User
Beiträge: 11
Registriert: Dienstag 5. Januar 2010, 13:55

Hi BlackJack,

danke für Deine Antwort.
Normalerweise bleibt eine Verbindung natürlich so lange offen, bis dass sie von einer der Seiten geschlossen wird.

Laut dieser Quelle: http://docs.python.org/howto/sockets.html wird aber zumindest bei Python die Verbindung direkt geschlossen:
When the connect completes, the socket s can be used to send in a request for the text of the page. The same socket will read the reply, and then be destroyed. That’s right, destroyed. Client sockets are normally only used for one exchange (or a small set of sequential exchanges).
Entweder verstehe ich das also falsch oder bei den Python-Sockets wird das halt so gemacht.
BlackJack

@Klappstuhl: Du verstehst das falsch. Da wird beschrieben was Dein Webbrowser macht wenn Du auf einen Link klickst. Das hat also noch nicht einmal zwingend etwas mit Python zu tun. Es sei denn Dein Webbrowser ist in Python implementiert. :-) Webbrowser benutzen ein Socket-Objekt in der Regel nur für eine Anfrage und die Antwort und werfen es dann weg. Weil ein Webserver nach der Antwort in der Regel auch sein Ende der Verbindung schliesst. Das heisst aber nicht das man Sockets so benutzen muss.
Klappstuhl
User
Beiträge: 11
Registriert: Dienstag 5. Januar 2010, 13:55

Hm, danke für die Aufklärung. Das habe ich tatsächlich so nicht realisiert.

Allerdings ist das vermutlich für mein Problem auch gar nicht so relevant. Der Stand jetzt ist, dass ich den Socket als Client starte (ich versuche mal ein vereinfachtes Beispiel zu geben):

Code: Alles auswählen

create_socket (socket.AF_INET, socket.SOCK_STREAM)
conn = ssl.wrap_socket (die_ganzen_parameter) # hier werden die Zertifikate etc. übergeben...
conn.setblocking(True)
conn.connect((dest_ip, dest_port))
conn.send("unser_toller_string")
conn.read(1024) # hier wird auch die korrekte Antwort empfangen. Also: SSL-Handshake klappt, Server erreichbar usw.
Danach wird dann eine Klasse

Code: Alles auswählen

RequestHandler(asynchat.async_chat, SimpleHTTPServer.SimpleHTTPRequestHandler)

aufgerufen, der der Socket "conn" in der __init__ übergeben wird.
Dieser RequestHandler bekommt auch immer exakt ein einziges mal einen Request und schickt auch die passende Antwort raus. Danach kann die Verbindung jedoch nicht mehr genutzt werden und wird nach etwa einer Minute automatisch geschlossen. Dabei wird jedoch weder von mir noch von der Gegenseite die Verbindung explizit geschlossen.

Vermutlich habe ich jetzt mit diesem Versuch der Erklärung noch mehr verwirrt, aber vielleicht weiß noch jemand einen Rat :)
BlackJack

@Klappstuhl: Da passiert wohl das, was bei der Beschreibung was Dein Webbrowser macht, auch steht: Nach dem Request wird die Verbindung geschlossen. So funktioniert HTTP nun mal. In der Regel eine Anfrage und Antwort pro Verbindung.
Klappstuhl
User
Beiträge: 11
Registriert: Dienstag 5. Januar 2010, 13:55

@BlackJack: Ja, das vermute ich ja auch. Deswegen die Frage, ob jemand schon mal versucht hat, Reverse HTTP über einen Python-Socket ans Laufen zu bringen. Eine Diskussion, ob Reverse HTTP sinnvoll ist aber bitte nicht (ich habe mich nicht erfolgreich dagegen wehren können :wink: )

Vielen Dank schon mal und einen guten Start ins Wochenende!
Klappstuhl
User
Beiträge: 11
Registriert: Dienstag 5. Januar 2010, 13:55

Um die Sache mal aufzuklären für die Nachwelt:

Es lag letzten Endes nicht am HTTP-Server (HTTP 1.1 unterstützt das Keep-alive der Verbindung, das funktionierte also).
Das Problem lag vielmehr am verwendeten Framework, welches das Ende einer Nachricht erkennen sollte. Dort wurde set_terminator() nach dem Erhalt der ersten Nachricht auf einen falschen Wert gesetzt und nicht zurück gesetzt.
Antworten