便秘的Python urllib2套接字

0 投票
1 回答
1236 浏览
提问于 2025-04-16 05:31

我在网上找了很久,想解决我在使用Python时遇到的问题。我想用urllib2来连接一个HTTP服务器,读取可能是无尽的数据流。这是一些互动通信的一部分,所以我需要能够获取到可用的数据,即使它不是一整个缓冲区的数据。可是,似乎没有办法让readreadline返回可用的数据。它会一直等待,直到整个(无尽的)数据流结束才会返回。

即使我用fnctl把底层的文件描述符设置为非阻塞,urllib2的文件对象还是会阻塞!! 总的来说,似乎没有办法让Python的文件对象在read时返回所有可用的数据,如果有数据的话,否则就阻塞。

我看到一些帖子,有人也在寻求这个问题的帮助,但我没有看到任何解决方案。这是怎么回事?我是不是漏掉了什么?这看起来是一个很正常的使用场景,怎么会搞得这么糟糕!我希望能利用urllib2检测配置的代理并使用分块编码,但如果它不配合,我就没办法了。

编辑:应要求,这里有一些示例代码

客户端:

connection = urllib2.urlopen(commandpath)
id = connection.readline()

现在假设服务器使用分块传输编码,写入一个块到数据流中,这个块包含一行数据,然后等待。连接仍然是打开的,但客户端在缓冲区中有数据在等待。

我无法让readreadline返回我知道它在等待的数据,因为它会尝试读取直到连接结束。在这种情况下,连接可能永远不会关闭,所以它要么会等待永远,要么等到不活动超时发生,导致连接中断。一旦连接中断,它才会返回,但这显然不是我想要的行为。

1 个回答

1

urllib2 是一个处理 HTTP 请求的工具,它是针对整个网页文档来工作的。我觉得如果不去修改 urllib2 的源代码,可能没有其他办法来解决这个问题。

不过,你可以使用普通的套接字(这时候你需要自己处理 HTTP 协议),然后调用 sock.recv(maxbytes),这样可以只读取当前可用的数据。

更新:你可以尝试在 urllib2 的连接上调用 conn.fp._sock.recv(maxbytes),而不是使用 conn.read(bytes)

撰写回答