it-swarm.com.de

Wie kann man das Timeout für die Socket-Recv-Methode von Python einstellen?

Ich muss Timeout für Pythons Socket Recv-Methode festlegen. Wie es geht?

88
Thoreller

Der typische Ansatz ist die Verwendung von select () , um zu warten, bis Daten verfügbar sind oder bis der Timeout auftritt. Rufen Sie recv() nur auf, wenn tatsächlich Daten verfügbar sind. Um sicherzugehen, setzen wir den Socket außerdem auf den nicht blockierenden Modus, um sicherzustellen, dass recv() niemals unbegrenzt blockiert wird. select() kann auch verwendet werden, um auf mehr als eine Steckdose gleichzeitig zu warten.

import select

mysocket.setblocking(0)

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

Wenn Sie viele offene Dateideskriptoren haben, ist poll () eine effizientere Alternative zu select().

Eine andere Option besteht darin, ein Zeitlimit für alle Vorgänge am Socket mithilfe von socket.settimeout() festzulegen. Ich sehe jedoch, dass Sie diese Lösung in einer anderen Antwort explizit abgelehnt haben.

100
46
nosklo

Wie bereits erwähnt, funktionieren beide select.select() und socket.settimeout() .

Beachten Sie, dass Sie settimeout möglicherweise zweimal aufrufen müssen, 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)
23
ubershmekel

Sie können ein Timeout einstellen, bevor Sie die Antwort erhalten, und nachdem Sie die Antwort erhalten haben, setzen Sie sie auf Keine zurück.

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

sock.settimeout(5.0)
data = sock.recv(1024)
sock.settimeout(None)
11
noriko

Das Timeout, nach dem Sie suchen, ist das Timeout des Verbindungs-Sockets, nicht das des primären Sockets, wenn Sie die Serverseite implementieren. Mit anderen Worten gibt es ein anderes Zeitlimit für das Verbindungssockelobjekt, das die Ausgabe der socket.accept()-Methode ist. Deshalb:

sock.listen(1)
connection, client_address = sock.accept()
connection.settimeout(5)    # This is the one that affects recv() method.
connection.gettimeout()     # This should result 5
sock.gettimeout()           # This outputs None when not set previously, if I remember correctly.

Wenn Sie die Client-Seite implementieren, wäre das einfach.

sock.connect(server_address)
sock.settimeout(3)
3
V123

Sie können socket.settimeout() verwenden, das ein ganzzahliges Argument akzeptiert, das die Anzahl Sekunden angibt. Beispielsweise setzt socket.settimeout(1) das Zeitlimit auf 1 Sekunde

0
Brian Zheng

Wie in früheren Antworten erwähnt, können Sie Folgendes verwenden: .settimeout() Beispiel:

import socket

s = socket.socket()

s.settimeout(1) # Sets the socket to timeout after 1 second of no activity

Host, port = "somehost", 4444
s.connect((Host, port))

s.send("Hello World!\r\n")

try:
    rec = s.recv(100) # try to receive 100 bytes
except socket.timeout: # fail after 1 second of no activity
    print("Didn't receive data! [Timeout]")
finally:
    s.close()

Ich hoffe das hilft!!

0
petrexxy

versuchen Sie dies, es verwendet das zugrunde liegende C.

timeval = struct.pack('ll', 2, 100)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeval)
0