web-dev-qa-db-fra.com

Comment définir le délai d'expiration sur la méthode socket recv de python?

J'ai besoin de définir timeout sur la méthode socket recv de python. Comment faire?

88
Thoreller

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.

100
Daniel Stutzbach
46
nosklo

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)
23
ubershmekel

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)
11
noriko

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)
3
V123

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.

0
Brian Zheng

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!!

0
petrexxy

essayez cela, il utilise le C. sous-jacent.

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