据我所知,当您调用socket.settimeout(value)
并且您将浮点值设置为大于0.0时,例如,当调用时,该套接字将提高scocket.timeoutsocket.recv
必须等待比指定值更长的时间。
但是想象一下,我必须接收大量数据,并且我必须打电话 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
这样,您的函数将不会影响调用它的代码的功能,无论它们与套接字的超时有何关系。