2010-04-27 10 views

Antwort

37
+10

Es dauert nicht das recv (Timeout) (zumindest wenn ich es versuchte). Nur das accept() ist abgelaufen. –

+6

Die socket.recv() scheint für mich nach dem Festlegen von socket.settimeout(), genau wie geplant, Timeout. Entwerfe ich das? Kann jemand anderes das bestätigen? – Aeonaut

+3

@Aeonaut Ich denke, dass dies die meiste Zeit recv() ausläuft, aber es gibt eine Wettlaufbedingung. In socket.recv() Python (2.6) -Aufrufen intern mit dem Timeout auswählen/abfragen und dann wird recv() direkt danach aufgerufen. Wenn Sie also einen blockierenden Sockel verwenden und zwischen diesen beiden Aufrufen der andere Endpunkt abstürzt, können Sie auf dem recv() endlos hängen bleiben. Wenn Sie einen nicht blockierenden Socket verwenden, ruft Python intern nicht select.select auf, daher denke ich, dass Daniel Stutzbachs Antwort der richtige Weg ist. –

88

Der typische Ansatz ist select() zu verwenden, zu warten, bis Daten verfügbar sind oder bis das Timeout auftritt. Rufen Sie recv() nur an, wenn Daten tatsächlich verfügbar sind. Um sicherzugehen, setzen wir den Socket auch auf den nicht blockierenden Modus, um zu garantieren, dass recv() niemals unbegrenzt blockiert wird. select() kann auch verwendet werden, um auf mehrere Sockets gleichzeitig zu warten.

import select 

mysocket.setblocking(0) 

ready = select.select([mysocket], [], [], timeout_in_seconds) 
if ready[0]: 
    data = mysocket.recv(4096) 

Wenn Sie eine Menge offener Dateien haben, ist poll() eine effizientere Alternative zu select().

Eine andere Option ist ein Timeout für alle Operationen auf dem Socket mit socket.settimeout(), aber ich sehe, dass Sie diese Lösung in einer anderen Antwort explizit abgelehnt haben.

+12

Verwenden Sie 'Select' ist gut, aber der Teil, wo Sie" Sie können nicht "sagen, ist irreführend, da es' socket.settimeout() 'gibt. – nosklo

+1

@nosklo Ich habe meine Antwort aktualisiert. –

+0

Es ist jetzt besser, aber ich sehe nicht, wo die Antwort "ausdrücklich abgelehnt" wurde. – nosklo

18

Wie erwähnt, funktionieren sowohl select.select() als auch socket.settimeout().

Hinweis: Sie müssen möglicherweise zweimal die settimeout für Ihre Bedürfnisse anrufen, z.

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
# accept can throw socket.timeout 
sock.settimeout(5.0) 
conn, addr = sock.accept() 

# recv can throw socket.timeout 
conn.settimeout(5.0) 
conn.recv(1024) 
+2

Ich denke, er ist in der gleichen Sache, in der ich bin, egal, wie Sie diese Funktion stochern und stoßen, es hängt. Ich habe jetzt 2 oder 4 Timeouts ausprobiert und es hängt immer noch. settimeout hängt auch. –

+0

Wenn Sie '.settimeout()' mehr als einmal aufrufen, können Sie die 'setdefaulttimeout()' Methode an erster Stelle aufrufen. – mvarge

9

Sie Timeout vor Erhalt der Antwort einstellen könnte und nach der Reaktion zurück auf None erhalten zu haben:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

sock.settimeout(5.0) 
data = sock.recv(1024) 
sock.settimeout(None) 
0

dies versuchen, es den zugrunde liegenden C verwendet

timeval = struct.pack('ll', 2, 100) 

s.setsockopt(socket.SOL_SOCKET,SO_RCVTIMEO, timeval) 
Verwandte Themen