在python中设置http响应读取方法的超时

发布于 2024-08-27 06:13:16 字数 177 浏览 6 评论 0原文

我正在用 python 构建一个下载管理器来娱乐,有时与服务器的连接仍然存在,但服务器不向我发送数据,因此(HTTPResponse 的)读取方法永远阻止我。例如,当我从位于我国境外的服务器下载时,就会发生这种情况,这会限制其他国家/地区的带宽。

如何设置read方法的超时时间(例如2分钟)?

谢谢,尼尔。

I'm building a download manager in python for fun, and sometimes the connection to the server is still on but the server doesn't send me data, so read method (of HTTPResponse) block me forever. This happens, for example, when I download from a server, which located outside of my country, that limit the bandwidth to other countries.

How can I set a timeout for the read method (2 minutes for example)?

Thanks, Nir.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

再可℃爱ぅ一点好了 2024-09-03 06:13:16

如果您陷入某些 Python 版本 < 执行此操作

import socket
socket.setdefaulttimeout(10.0)  # or whatever

2.6,一种(不完美但可用)方法是在开始使用 httplib 之前 。文档位于此处,并明确指出 < code>setdefaulttimeout 自 Python 2.3 起可用——从您执行此调用到您再次调用同一函数时创建的每个套接字都将使用 10 秒的超时。您可以在设置新超时之前使用 getdefaulttimeout ,如果您想保存之前的超时(包括无超时)以便以后可以恢复它(使用另一个 setdefaulttimeout)。

当你需要使用一些旧的高级库时,这些函数和习惯用法非常有用,这些库使用Python套接字,但没有给你一个设置超时的好方法(当然最好使用更新的)更高级别的库,例如 2.6 附带的 httplib 版本或本例中的第三方 httplib2,但这并不总是可行,并且使用默认超时设置可能是一个很好的解决方法)。

If you're stuck on some Python version < 2.6, one (imperfect but usable) approach is to do

import socket
socket.setdefaulttimeout(10.0)  # or whatever

before you start using httplib. The docs are here, and clearly state that setdefaulttimeout is available since Python 2.3 -- every socket made from the time you do this call, to the time you call the same function again, will use that timeout of 10 seconds. You can use getdefaulttimeout before setting a new timeout, if you want to save the previous timeout (including none) so that you can restore it later (with another setdefaulttimeout).

These functions and idioms are quite useful whenever you need to use some older higher-level library which uses Python sockets but doesn't give you a good way to set timeouts (of course it's better to use updated higher-level libraries, e.g. the httplib version that comes with 2.6 or the third-party httplib2 in this case, but that's not always feasible, and playing with the default timeout setting can be a good workaround).

<逆流佳人身旁 2024-09-03 06:13:16

您必须在 HTTPConnection 初始化期间设置它。

注意:如果您使用的是较旧版本的 Python,则可以安装 httplib2;许多人认为它是 httplib 的更好替代品,并且它确实支持 超时
不过,我从未使用过它,我只是报告文档和博客的内容。

You have to set it during HTTPConnection initialization.

Note: in case you are using an older version of Python, then you can install httplib2; by many, it is considered a superior alternative to httplib, and it does supports timeout.
I've never used it, though, and I'm just reporting what documentation and blogs are saying.

酷遇一生 2024-09-03 06:13:16

如果下载很大,设置默认超时可能会提前中止下载,而不是仅在停止接收超时值的数据时中止。 HTTPlib2 可能是正确的选择。

Setting the default timeout might abort a download early if it's large, as opposed to only aborting if it stops receiving data for the timeout value. HTTPlib2 is probably the way to go.

淡忘如思 2024-09-03 06:13:16

5年后,但希望这能对其他人有所帮助……

我绞尽脑汁试图弄清楚这一点。我的问题是服务器返回损坏的内容,因此返回的数据比它想象的要少。

我想出了一个令人讨厌的解决方案,但似乎工作正常。这里是这样的:

# NOTE I directly disabling blocking is not necessary but it represents
# an important piece to the problem so I am leaving it here.
# http_response.fp._sock.socket.setblocking(0)
http_response.fp._sock.settimeout(read_timeout)
http_response.read(chunk_size)

注意 这个解决方案也适用于python requests ANY 实现普通 python 套接字的库(应该是全部? )。你只需要更深入一些:

resp.raw._fp.fp._sock.socket.setblocking()
resp.raw._fp.fp._sock.settimeout(read_timeout)
resp.raw.read(chunk_size)

在撰写本文时,我还没有尝试过以下方法,但理论上它应该有效:

resp = requests.get(some_url, stream=True)
resp.raw._fp.fp._sock.socket.setblocking()
resp.raw._fp.fp._sock.settimeout(read_timeout)
for chunk in resp.iter_content(chunk_size):
      # do stuff

解释

我在阅读 在socket.recv上设置超时

归根结底,任何http请求都有一个套接字。对于 httplib,该套接字位于 resp.raw._fp.fp._sock.socketresp.raw._fp.fp._sock 是一个 socket._fileobj (老实说我没有深入研究),我想它是 settimeout code> 方法在内部将其设置在 socket 属性上。

5 years later but hopefully this will help someone else...

I was wrecking my brain trying to figure this out. My problem was a server returning corrupt content and thus giving back less data than it thought it had.

I came up with a nasty solution that seems to be working properly. Here it goes:

# NOTE I directly disabling blocking is not necessary but it represents
# an important piece to the problem so I am leaving it here.
# http_response.fp._sock.socket.setblocking(0)
http_response.fp._sock.settimeout(read_timeout)
http_response.read(chunk_size)

NOTE This solution also works for the python requests ANY library that implements the normal python sockets (which should be all of them?). You just have to go a few levels deeper:

resp.raw._fp.fp._sock.socket.setblocking()
resp.raw._fp.fp._sock.settimeout(read_timeout)
resp.raw.read(chunk_size)

As of this writing, I have not tried the following but in theory it should work:

resp = requests.get(some_url, stream=True)
resp.raw._fp.fp._sock.socket.setblocking()
resp.raw._fp.fp._sock.settimeout(read_timeout)
for chunk in resp.iter_content(chunk_size):
      # do stuff

Explanation

I stumbled upon this approach when reading this SO question for setting a timeout on socket.recv

At the end of the day, any http request has a socket. For the httplib that socket is located at resp.raw._fp.fp._sock.socket. The resp.raw._fp.fp._sock is a socket._fileobj (which I honestly didn't look far into) and I imagine it's settimeout method internally sets it on the socket attribute.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文