J'ai besoin de définir timeout sur la méthode socket recv de python. Comment faire?
L'approche typique consiste à utiliser select () à attendre que les données soient disponibles ou que le délai d'attente se soit écoulé. Appelez uniquement recv()
lorsque les données sont réellement disponibles. Par sécurité, nous avons également défini le socket en mode non bloquant pour garantir que recv()
ne bloquera jamais indéfiniment. select()
peut également être utilisé pour attendre plusieurs prises à la fois.
import select
mysocket.setblocking(0)
ready = select.select([mysocket], [], [], timeout_in_seconds)
if ready[0]:
data = mysocket.recv(4096)
Si vous avez beaucoup de descripteurs de fichiers ouverts, poll () est une alternative plus efficace à select()
.
Une autre option consiste à définir un délai d'expiration pour toutes les opérations sur le socket à l'aide de socket.settimeout()
, mais je constate que vous avez explicitement rejeté cette solution dans une autre réponse.
il y a socket.settimeout()
Comme mentionné, select.select()
et socket.settimeout()
fonctionnera.
Notez que vous devrez peut-être appeler settimeout
deux fois pour répondre à vos besoins, par exemple.
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)
Vous pouvez définir un délai d'expiration avant de recevoir la réponse et après l'avoir reçue, réglez de nouveau sur Aucune
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5.0)
data = sock.recv(1024)
sock.settimeout(None)
Le délai d'expiration que vous recherchez correspond au délai d'expiration du socket de connexion, pas à celui du socket principal, si vous implémentez le côté serveur. En d'autres termes, il existe un autre délai d'attente pour l'objet socket de connexion, qui est la sortie de la méthode socket.accept()
. Donc:
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.
Si vous implémentez le côté client, ce serait simple.
sock.connect(server_address)
sock.settimeout(3)
Vous pouvez utiliser socket.settimeout()
qui accepte un argument entier représentant le nombre de secondes. Par exemple, socket.settimeout(1)
définira le délai d'attente à 1 seconde.
Comme mentionné dans les réponses précédentes, vous pouvez utiliser quelque chose comme: .settimeout()
Par exemple:
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()
J'espère que ça aide!!
essayez cela, il utilise le C. sous-jacent.
timeval = struct.pack('ll', 2, 100)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeval)