Wie leer ein socket in python?
Muss ich leeren Sie die Daten auf einem socket (sicherstellen, dass es nichts zu erhalten).
Leider gibt es keine Funktion in der python-socket-Modul.
Habe ich umgesetzt, etwas so:
def empty_socket(sock):
"""remove the data present on the socket"""
input = [sock]
while 1:
inputready, o, e = select.select(input,[],[], 0.0)
if len(inputready)==0: break
for s in inputready: s.recv(1)
Was denkst du? Gibt es eine bessere Weise, das zu tun?
Update: ich will nicht zu ändern Sie das socket-timeout. Was ist der Grund, warum ich lieber wählen, um gelesen zu werden.
Update: Die ursprüngliche Frage war mit dem "flush" Begriff. Es scheint, dass 'leer' ist ein besserer Begriff.
Update - 2010-02-27 :
Ich habe bemerkt einen Fehler, wenn das paar hat sich geschlossen. Die inputready ist immer gefüllt mit den sockets. Ich behoben, indem eine maximale Anzahl von loops. Gibt es eine bessere Lösung?
- das ist nicht wirklich ein "flush" pro sagen. Werfen Sie einen Blick auf die Beispiele in der Dokumentation für das Lesen von einem socket. docs.python.org/library/socket.html#example
- Haben Sie sich überlegt, Verdrillte für Ihr Programm stattdessen? Wenn Sie es wüssten, würden Sie nie brauchen, um zu tun etwas wie dieses. Verdreht sofort ziehen alle Daten aus der Steckdose und stellen es Ihnen immer, wenn einer ankommt, so brauchen Sie nicht, um Chaos über mit hässlichen details wie die select () - problem beschrieben durch Thomas ' Antwort unten.
- Nein, ich habe nicht betrachten Sie Verdreht, weil ich wollte, dass die standard-python-Modul, um zu vermeiden, dass externe Abhängigkeiten. Vielen Dank für diesen Kommentar, ich werde schauen, Twisted und vielleicht überdenken, meine Wahl
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie von "flush" bedeutet wegwerfen, ausstehende eingehende Daten, dann können Sie entweder wählen Sie() wie Sie tun, oder legen Sie die Buchse auf nicht blockierenden und lese in einer Schleife, bis Sie aus Daten.
Beachten Sie auch, dass (aus der Linux manpage):
Unechte Systemupdate-Benachrichtigung für Select-System-call
Und wie bereits erwähnt, von anderen, "flush" bezieht sich normalerweise auf die Ausgabe.
Mit
select.select
ist gute Praxis, wie in der Socket Programmierung HOWTO. Sie müssen der socket als nicht-blockierend, mitsock.setblocking(0)
.Nur ein Kommentar zur Nomenklatur:
flush
ist in der Regel verbunden mit Ausgabe Operationen.Für UDP-Pakete, ich habe die folgenden:
Nach dem erstellen des socket-Optionen setzen, und die Bindung, die ich verwenden
socket.settimeout()
. Beachten Sie die Dokumentation fürsetblocking()
gibt einige Informationen, die, dass dersettimeout()
nicht - wenn Sie möchten, dass Ihre socket-Operationen zu blockieren, sollten Sie nur verwendensettimeout()
zum festlegen der timeout-Zeit.setblocking()
legt einfach ein unendliches timeout auf. (Ich hatte einen bug Aufrufsettimeout()
gefolgt vonsetblocking(1)
.)Mein "Puffer leeren" - Funktion ist dann nur dieses ("Listener" ist meine Buchse):
def FlushListen(self):
while 1:
try:
PacketBytes = self.__Listener.recv(1024)
except:
break;
Mit einem timeout von 1 Sekunde, so wird Lesen Sie alle UDP-Pakete und dann wieder 1 Sekunde nach gibt es keine Daten.
In meinem Fall verwende ich es, nur zu reden, zwischen zwei Programmen auf demselben PC, also könnte ich einfach unten meine timeout-aber Geschwindigkeit ist nicht ein Problem, also ich bin mit diesem feinen.
Entsprechend einige andere links gepostet, sollte diese Arbeit mit Daten-streams.
Cant wir einfach weiter Lesen bis der Puffer leer ist?
Nicht sicher, ob dies funktionieren wird, aber man könnte anfügen einer Datei-Objekt, das socket-file-Deskriptor, und rufen Sie die
flush()
Methode auf das Datei-Objekt:Diese funktioniert nicht in Windows, da der Deskriptor zurückgegeben
fileno()
können nicht übergeben werdenos.fdopen()
im Windows