
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hallo, ich versuche gerade für einen Bugreport einen (fast) minimalen Socket Server und Client zu bauen. Der Server soll einen Request bearbeiten und sich dann beenden. Der Client liest nur vom Server. Nachdem Client und Server ihre Arbeit getan haben, hängt aber noch eine Socket-Verbindung in Status TIME_WAIT herum. Ich finde nicht, wo der Haken ist. Nur, wenn ich das file.read() im Client weg lasse, wird der Socket sauber geschlossen. Was mache ich falsch? ...8<-------- Server ------- import SocketServer import sys MyRequestHandler = SocketServer.StreamRequestHandler if sys.argv[1:]: port = int(sys.argv[1]) else: port = 8000 server_address = ('', port) d = SocketServer.TCPServer(server_address, MyRequestHandler) print "Serving on %s port %s ..." % d.socket.getsockname() # handle one request only d.handle_request() print d.socket d.server_close() ...8<----------------------- ...8<-------- Client ------- import socket import sys if sys.argv[1:]: port = int(sys.argv[1]) else: port = 8000 server_address = ('localhost', port) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(server_address) file = sock.makefile() # wenn man die nächste Zeile weg laesst, schliesst der socket sauber print file.read(), file.close() sock.close() ...8<----------------------- - -- Schönen Gruß - Regards Hartmut Goebel Goebel Consult - Wir machen IT sicher - www.goebel-consult.de -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Mandriva - http://enigmail.mozdev.org iQEVAwUBRfhmv8zajR0mSa83AQIingf+LFh3Z+z1TF52womIBytSrXa77adk6Hsg LgRTfsBZm/dBt2DXFEx1XyudUmaX8AMN1x2QoOLnBakgji3QL2dOHZmXysL0fSeO RtHN4CfQVkS2zl296FlXMAhxjx2f734RVUrH6aZhggrG8aeJsSLW1UHbYuMBZTbJ 6yioje4hS25HDCf7RCAZsrMT8UZ2b9OodazkqU7w7JVrcdisxVTquu9f3mfCsaTo oOA3k5s5z0GO10PuyOf80ZBMjl8wTl/xxFZN//pDkPIM9Q6j1Jffre14egnZfrax Ix+HVxn02n4bSuQuFehMYtj8qsOi6+aiBb6wHstndhOMAyulFiR0jw== =vwaI -----END PGP SIGNATURE-----

Hallo Hartmut, Hartmut Goebel schrieb:
Was mache ich falsch?
nischt. Klingt nach: http://www.google.de/search?q=python+setsockopt+reuse Einfach entsprechend die Option via setsockopt setzen. Möglich, dass der SocketServer ein Attribut "reuse_address" o.ä. bietet. HTH, Florian

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hallo Florian,
Hartmut Goebel schrieb:
Was mache ich falsch?
nischt. Klingt nach:
Es kommt mir aber sehr komisch vor, dass die TCP-Verbindung nicht sauber abgebaut wird. Irgendwas scheint mir da doch faul. - -- Schönen Gruß - Regards Hartmut Goebel Goebel Consult - Wir machen IT sicher - www.goebel-consult.de -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Mandriva - http://enigmail.mozdev.org iQEVAwUBRfhrHszajR0mSa83AQKr0Qf/TTggAGjqO0XD+jmJtNtendeifd/ZPVCV jB38wAi/wZB1Qq9IP4JLz69j4r4uQaiFKXbHIYp5yTsu8YtKLOrEi+t28isthtHn OLsj0Sk8xjnlYLRluEwpi+y3PufGpXyYYYNYH/9nODQOZAJYkjg2od3xhirlcCXc CNZYpOq7KnSTmZEsfXk3EJGPWyFXBFW9AlldvNMoFyaEKSNXuNFytDAXNY5lAu87 OpnTInyNQF6ldII9F1UJbANoYMFrJfck2a23dtEa2NuldWDq6+ZdWKpuHRavuzoQ 5RwnB0LsMEmgXUzME3cl8ECtDz9v1EIQZ7YrddVnVHXD3Upde3EJ+w== =bVQ3 -----END PGP SIGNATURE-----

Hallo Hartmut, Hartmut Goebel schrieb:
Hartmut Goebel schrieb:
Was mache ich falsch? nischt. Klingt nach:
Es kommt mir aber sehr komisch vor, dass die TCP-Verbindung nicht sauber abgebaut wird. Irgendwas scheint mir da doch faul.
Ne, AFAIK ist TIME_WAIT nach geschlossenem Socket eine Zeitsperre für TCP-Verbindungen, um sicherzustellen, dass die Verbindungen auch wirklich korrekt geschlossen wurden und dementsprechend dafür genug Zeit hatten (die Sperrzeit liegt bei ein paar Minuten). Wenn keine Verbindungen existierten/existieren, so besteht auch kein Grund für eine Sperrzeit (daher der Effekt, dass das TIME_WAIT erst nach einer Clientaktivität auftritt). Möchtest du den Port vor der Sperrzeit wieder benutzen, so nutze einfach die REUSE-Option, die du für einen low-level-Socket über die Methode setsockopt aktivieren kannst. HTH, Florian

Florian Schlachter schrieb:
Ne, AFAIK ist TIME_WAIT nach geschlossenem Socket eine Zeitsperre für TCP-Verbindungen, um sicherzustellen, dass die Verbindungen auch wirklich korrekt geschlossen wurden und dementsprechend dafür genug Zeit hatten (die Sperrzeit liegt bei ein paar Minuten). Wenn keine Verbindungen existierten/existieren, so besteht auch kein Grund für eine Sperrzeit (daher der Effekt, dass das TIME_WAIT erst nach einer Clientaktivität auftritt).
Ergänzend ein paar Zitate aus dem RFC 793[1]: "TIME-WAIT STATE The only thing that can arrive in this state is a retransmission of the remote FIN. Acknowledge it, and restart the 2 MSL timeout." sowie "TIME-WAIT - represents waiting for enough time to pass to be sure the remote TCP received the acknowledgment of its connection termination request." Gruß Florian [1] http://tools.ietf.org/html/rfc793

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hallo, Ups, da ist der Handle doch etwas zu klein ausgefallen. Mit dem der gar nicht tut, gibt es auch keine Probleme. Aber dieser, der ein Paar Zeichen über die Leitung schick, verursacht die Probleme. class MyRequestHandler(SocketServer.StreamRequestHandler): def handle(self): print >> self.rfile, "Hallo Client" Herausgefunden ahbe ich noch, dass der Verbindungs-Abbau unvollständig ist: 8000 > 43211 FIN, ACK 43211 > 8000 FIN, ACK 8000 > 43211 ACK Es fehlt also das ACK für das Beenden der Verbindung ducht den Server. - -- Schönen Gruß - Regards Hartmut Goebel Goebel Consult - Wir machen IT sicher - www.goebel-consult.de -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Mandriva - http://enigmail.mozdev.org iQEVAwUBRfhuFMzajR0mSa83AQLjzQf/TJuZIGK0uEIRWqAXPC0rdHhJYUegdvRT 3DGxssl4E64kMBdtH//7pxNRM9lePEOSaxPlKdpuIuQdzUgLpz3LvI8NKSS1HJux whwl0g0Y79+dCbmsqIrtjrJJLQxlnzRcivEEKhaX4Gn545eZKev23kxcaHJ0IQcb ofjxC1VIzRbNiHJLPZkCzA8oiytXlK60eOWAziCXbbSgvuIhsvo4aELW20wOT0wL gVkbP0EPFm4nfMinQJ0E36nCFeEM35xPZG6HQ4VzrHcpsUzP7Ic8mWkHIKC9/dWK YE5TgKf/7txsOf66LZFWRyJ+MjD4YcQQmNv4rgsaju2oKstnIe54zQ== =9lMz -----END PGP SIGNATURE-----

Hallo Hartmut, Am Mittwoch, 14. März 2007 22:50 schrieb Hartmut Goebel:
Herausgefunden ahbe ich noch, dass der Verbindungs-Abbau unvollständig ist:
8000 > 43211 FIN, ACK
der Server bestätigt das vorherige TCP-Paket und setzt FIN, um das Schließen seiner Seite der Verbindung zu verkünden.
43211 > 8000 FIN, ACK
der Client bestätigt das vorherige TCP-Paket und setzt FIN, um das Schließen seiner Seite der Verbindung zu verkünden.
8000 > 43211 ACK
Der Server bestätigt das letzte Paket des Clients. Der Socket befindet sich nun im Status TIME_WAIT, um zu verhindern, dass eine andere Anwendung diesen Socket (genauer TCP-Port 43211) benutzt und eventuell verspätet eintreffende TCP-Pakete der vorherigen Nutzung bekommt. Wenn Du diesen Schutz nicht möchtest, setze SO_REUSEADDR, wie an anderer Stelle bereits vorgeschlagen wurde.
Es fehlt also das ACK für das Beenden der Verbindung ducht den Server.
Es ist alles in Ordnung. Wenn das gezeigte Verhalten nicht richtig wäre, würde das bedeuten, dass der TCP/IP-Stack Deines Betriebssystems kaputt ist, nicht das Python Programm. Gruß Karsten -- Deutsche Übersetzungen von Fachbegriffen aus der Computerwelt: Modem (Modulator/Demodulator): VerEnt (Verwurschteler/Entwurschteler)

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hallo Karsten,
Der Server bestätigt das letzte Paket des Clients. Der Socket befindet sich nun im Status TIME_WAIT, um zu verhindern, dass eine andere Anwendung diesen Socket (genauer TCP-Port 43211) benutzt und eventuell verspätet eintreffende TCP-Pakete der vorherigen Nutzung bekommt.
IC. Und ich dachte, ich kenne mich mit TCP aus :-\ Habe das eben mit natcat nachgestellt (weil ich es nicht glauben wollte ;-) und da ist es genau so. Nur verwendet netcat seit 2002 standardmaäßig SO_REUSEADDR -- wie wohl die meisten Anwendungen --, daher ist das nicht aufgefallen. Danke - -- Schönen Gruß - Regards Hartmut Goebel Goebel Consult - Wir machen IT sicher - www.goebel-consult.de -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Mandriva - http://enigmail.mozdev.org iQEVAwUBRfkRn8zajR0mSa83AQId3Qf/cwMfpby84hMN1TAco26mxgWBPB+B8ihl W9/W35VjusZhB5lJTFPPqjT8iQ5K7bqAZKPh+9w9yOcqouMAH0wo0eMQ68VEE5BA ny4v3u4uGuFrYLZ9RPR7b+CJw56rosFXCAUSZtiQC3MiTOluc7F8kBKkZ8tCDd5c GF74TChAriEZjQfVSyUC5lmsu8qhB9Q9XGWB5q6v8yOz20SR3YQ1IUJVrlP87mvS jHOFR5NfTPv6HilIYb+kYc7YZDqJH3Rszrievl57CRuIlYnU/Nt6wVKKcMjMsajW cpGFV+G4XgvJTK2rKX80zOVouku5jLRtHXYzl9WXqHPgwf8CyBxxOQ== =YniV -----END PGP SIGNATURE-----
participants (3)
-
Florian Schlachter
-
Hartmut Goebel
-
Karsten Schulz