如何正确使用python socket.settimeout()
据我所知,当您调用socket.settimeout(value)
并且将float值设置为大于0.0时,例如,当调用socket.recv
必须等待比指定值更长的时间时,该套接字将提高scocket.timeout
。
但是假设我必须接收大量数据,并且必须recv()
多次调用,那么settimeout会如何影响它?
给出以下代码:
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)
代码的第三行将套接字的超时设置为20秒。超时是否会在每次迭代时重置?仅当这些迭代之一花费超过20秒时才会提高超时吗?
A)如果要花费所有超过20秒的时间来接收所有期望的数据,我该如何对其进行重新编码,以便引发异常?
B)如果在读取所有数据后没有将超时设置为“无”,会发生什么不好的事情吗?(连接保持活动状态,将来可能会请求更多数据)。
-
超时适用于对套接字读/写操作的单个调用。因此,下次通话将再次为20秒。
A)要让多个后续呼叫共享一个超时,您必须手动对其进行跟踪。遵循以下原则:
deadline = time.time() + 20.0 while not data_received: if time.time() >= deadline: raise Exception() # ... socket.settimeout(deadline - time.time()) socket.read() # ...
B)任何使用带有超时的套接字并且不准备处理
socket.timeout
异常的代码都可能会失败。在开始操作之前记住套接字的超时值,并在完成后将其恢复是更可靠的: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
这样,您的函数将不会影响调用它的代码的功能,无论它们与套接字的超时有何关系。