使用urllib2读取流时连接中断无法恢复

8 投票
2 回答
2770 浏览
提问于 2025-04-15 11:20

在我尝试让我的一个Python应用程序在连接中断时更加稳定时,我发现用urllib2的http-stream调用read函数可能会让脚本一直卡住。

我原以为read函数会有超时设置,最终会抛出一个异常,但实际上,当在调用read函数时连接中断时,似乎并不是这样。

下面是会导致这个问题的代码:

import urllib2

while True:
    try:
        stream = urllib2.urlopen('http://www.google.de/images/nav_logo4.png')
        while stream.read(): pass
        print "Done"
    except:
        print "Error"

(如果你试这个脚本,可能需要多次中断连接,才能达到脚本永远无法恢复的状态。)

我通过Winpdb观察了这个脚本,并截图了脚本永远无法恢复的状态(即使网络恢复了也不行)。

Winpdb http://img10.imageshack.us/img10/6716/urllib2.jpg

有没有办法创建一个Python脚本,即使在网络连接中断的情况下也能可靠地继续工作?(我希望避免在额外的线程中处理这个问题。)

2 个回答

2

这是个好问题,我也很想知道答案。我能想到的唯一解决办法就是使用在Python文档中解释的信号技巧。对于你的情况,可能更像是:

import signal
import urllib2

def read(url):
    stream = urllib2.urlopen(url)
    return stream.read()

def handler(signum, frame):
    raise IOError("The page is taking too long to read")

# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)

# This read() may hang indefinitely
try:
    output = read('http://www.google.de/images/nav_logo4.png')
except IOError:
    # try to read again or print an error
    pass

signal.alarm(0)          # Disable the alarm
7

你可以试试下面这个:

import socket
socket.setdefaulttimeout(5.0)
   ...
try:
   ...
except socket.timeout:
   (it timed out, retry)

撰写回答