如何正确使用python socket.settimeout()

发布于 2021-01-29 16:05:42

据我所知,当您调用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)如果在读取所有数据后没有将超时设置为“无”,会发生什么不好的事情吗?(连接保持活动状态,将来可能会请求更多数据)。

关注者
0
被浏览
184
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    超时适用于对套接字读/写操作的单个调用。因此,下次通话将再次为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
    

    这样,您的函数将不会影响调用它的代码的功能,无论它们与套接字的超时有何关系。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看