如何正确使用 python socket.settimeout() [英] How to use python socket.settimeout() properly

查看:70
本文介绍了如何正确使用 python socket.settimeout()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,当您调用 socket.settimeout(value) 并设置大于 0.0 的浮点值时,该套接字将在调用时引发 scocket.timeout,例如, socket.recv 必须等待比指定值更长的时间.

As far as I know, when you call socket.settimeout(value) and you set a float value greater than 0.0, that socket will raise a scocket.timeout when a call to, for example, socket.recv has to wait longer than the value specified.

但是假设我必须接收大量数据,并且必须多次调用 recv(),那么 settimeout 对此有何影响?

But imagine I have to receive a big amount of data, and I have to call recv() several times, then how does settimeout affect that?

给定以下代码:

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 秒时才会引发超时吗?

The third line of the code sets the timeout of the socket to 20 seconds. Does that timeout reset every iteration? Will timeout be raised only if one of those iteration takes more than 20 seconds?

A) 如果接收所有预期数据的时间超过 20 秒,我该如何重新编码以使其引发异常?

A) How can I recode it so that it raises an exception if it is taking more than 20 seconds to receive all the expected data?

B) 如果我在读取所有数据后没有将超时设置为 None,会发生什么不好的事情吗?(连接保持活动状态,将来可能会请求更多数据).

B) If I don't set the timeout to None after we read all data, could anything bad happen? (the connection is keep-alive and more data could be requested in the future).

推荐答案

超时适用于对套接字读/写操作的单个调用.所以下一次调用又是 20 秒.

Timeout applies to a single call to socket read/write operation. So next call it will be 20 seconds again.

A) 要让多个后续调用共享超时,您必须手动跟踪它.一些类似的东西:

A) To have a timeout shared by several consequential calls, you'll have to track it manually. Something along these lines:

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 异常的代码都可能会失败.在开始操作之前记住套接字的超时值更可靠,并在完成后恢复它:

B) Any code that's using a socket with a timeout and isn't ready to handle socket.timeout exception will likely fail. It is more reliable to remember the socket's timeout value before you start your operation, and restore it when you are done:

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

这样,您的函数不会影响调用它的代码的功能,无论它们中的任何一个对套接字的超时做了什么.

This way, your function will not affect the functioning of the code that's calling it, no matter what either of them do with the socket's timeout.

这篇关于如何正确使用 python socket.settimeout()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆