Cómo usar python socket.settimeout () correctamente

Por lo que sé, cuando llama a socket.settimeout(value) y establece un valor flotante mayor que 0.0, ese socket levantará un scocket.timeout cuando una llamada a, por ejemplo, socket.recv tenga que esperar más que el valor especificado

Pero imagina que tengo que recibir una gran cantidad de datos, y debo llamar a recv() varias veces, entonces, ¿cómo afecta eso a settimeout?

Dado el siguiente código:

 to_receive = # an integer representing the bytes we want to receive socket = # a connected socket socket.settimeout(20) received = 0 received_data = b"" while received < to_receive: tmp = socket.recv(4096) if len(tmp) == 0: raise Exception() received += len(tmp) received_data += tmp socket.settimeout(None) 

La tercera línea del código establece el tiempo de espera del socket en 20 segundos. ¿Ese tiempo de espera restablece cada iteración? ¿Se boostá el tiempo de espera solo si una de esas iteraciones dura más de 20 segundos?

A) ¿Cómo puedo recodificarlo para que genere una excepción si tarda más de 20 segundos en recibir todos los datos esperados?

B) Si no configuro el tiempo de espera en Ninguno después de leer todos los datos, ¿podría pasar algo malo? (La conexión es de mantenimiento y se pueden solicitar más datos en el futuro).

El tiempo de espera se aplica a una sola llamada a la operación de lectura / escritura del socket. Así que la próxima llamada será de 20 segundos de nuevo.

A) Para tener un tiempo de espera compartido por varias llamadas consecutivas, deberá realizar un seguimiento manual. Algo a lo largo de estas líneas:

 deadline = time.time() + 20.0 while not data_received: if time.time() >= deadline: raise Exception() # ... socket.settimeout(deadline - time.time()) socket.read() # ... 

B) Cualquier código que use un socket con un tiempo de espera y no esté listo para manejar la excepción de socket.timeout probablemente fallará. Es más confiable recordar el valor de tiempo de espera del socket antes de comenzar la operación y restaurarlo cuando haya terminado:

 def my_socket_function(socket, ...): # some initialization and stuff old_timeout = socket.gettimeout() # Save # do your stuff with socket socket.settimeout(old_timeout) # Restore # etc 

De esta manera, su función no afectará el funcionamiento del código que lo está llamando, independientemente de lo que cualquiera de ellos haga con el tiempo de espera del socket.

El tiempo de espera se aplica a cada llamada a recv ().

A) simplemente use su tiempo de espera existente y llame a recv (para recibir) – Es decir, trate de recibir todos los datos en una llamada de recibo – de hecho, no veo por qué no debería usar esto como la forma predeterminada.

B) No puede pasar nada malo, pero cualquier otro código que use ese zócalo debe ser consciente del tiempo de espera de la gestión.

En su código existente, no debería ser recv () call recv (max (4096, to_receive-recibe)) – de esa manera no consumirá involuntariamente ningún dato que sigue después de los to_receive bytes.

Ver mi script de servidor, tendrá la idea de utilizarlo correctamente.

 import socket import sys fragments = [] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("192.168.1.4",9001)) s.listen(5) while True: c,a = s.accept() c.settimeout(10.0) print "Someone came in Server from %s and port %s" %(a[0],a[1]) c.send("Welcome to system") while True: chunk = c.recv(2048) if not chunk.strip(): break else: fragments.append(chunk) continue combiner = "".join(fragments) print combiner shutdown = str(raw_input("Wanna Quit(Y/y) or (N/n): ")) if shutdown == 'Y' or shutdown == 'y': c.close() sys.exit() else: continue 

Este script es solo para darle una idea sobre el socket.settimeout ().