Python 关闭urllib2连接

Python 关闭urllib2连接,python,ftp,connection,urllib2,Python,Ftp,Connection,Urllib2,我使用urllib2从ftp和http服务器加载文件 有些服务器只支持每个IP一个连接。问题是,urllib2不会立即关闭连接。请看示例程序 from urllib2 import urlopen from time import sleep url = 'ftp://user:pass@host/big_file.ext' def load_file(url): f = urlopen(url) loaded = 0 while True: data

我使用urllib2从ftp和http服务器加载文件

有些服务器只支持每个IP一个连接。问题是,urllib2不会立即关闭连接。请看示例程序

from urllib2 import urlopen
from time import sleep

url = 'ftp://user:pass@host/big_file.ext'

def load_file(url):
    f = urlopen(url)
    loaded = 0
    while True:
        data = f.read(1024)
        if data == '':
            break
        loaded += len(data)
    f.close()
    #sleep(1)
    print('loaded {0}'.format(loaded))

load_file(url)
load_file(url)
代码从仅支持1个连接的ftp服务器加载两个文件(此处两个文件相同)。这将打印以下日志:

loaded 463675266
Traceback (most recent call last):
  File "conection_test.py", line 20, in <module>
    load_file(url)
  File "conection_test.py", line 7, in load_file
    f = urlopen(url)
  File "/usr/lib/python2.6/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python2.6/urllib2.py", line 391, in open
    response = self._open(req, data)
  File "/usr/lib/python2.6/urllib2.py", line 409, in _open
    '_open', req)
  File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.6/urllib2.py", line 1331, in ftp_open
    fw = self.connect_ftp(user, passwd, host, port, dirs, req.timeout)
  File "/usr/lib/python2.6/urllib2.py", line 1352, in connect_ftp
    fw = ftpwrapper(user, passwd, host, port, dirs, timeout)
  File "/usr/lib/python2.6/urllib.py", line 854, in __init__
    self.init()
  File "/usr/lib/python2.6/urllib.py", line 860, in init
    self.ftp.connect(self.host, self.port, self.timeout)
  File "/usr/lib/python2.6/ftplib.py", line 134, in connect
    self.welcome = self.getresp()
  File "/usr/lib/python2.6/ftplib.py", line 216, in getresp
    raise error_temp, resp
urllib2.URLError: <urlopen error ftp error: 421 There are too many connections from your internet address.>

有没有办法强制关闭连接,以便第二次下载不会失败?

Alex Martelli回答了类似的问题。请阅读以下内容:

简言之:

import contextlib

with contextlib.closing(urllib.urlopen(u)) as x:
    # ...

我想这是因为连接没有关闭()

注意close()释放资源 与一个连接相关联,但是没有 不一定要关闭连接 马上。如果你想关闭 及时联系,打电话 关闭()之前关闭()

您可以在f.close()之前尝试类似的操作:


(是的..如果这样做有效,它是不对的(tm),但你会知道问题出在哪里。)

至于Python 2.7.1 urllib2确实泄漏了一个文件描述符:
原因确实是文件描述符泄漏。我们还发现,使用jython时,问题比使用cpython时明显得多。 一位同事提出了这一解决方案:

fdurl = urllib2.urlopen(req,timeout=self.timeout) realsock = fdurl.fp._sock.fp._sock** # we want to close the "real" socket later req = urllib2.Request(url, header) try: fdurl = urllib2.urlopen(req,timeout=self.timeout) except urllib2.URLError,e: print "urlopen exception", e realsock.close() fdurl.close() fdurl=urllib2.urlopen(请求,超时=self.timeout) realsock=fdurl.fp.\u sock.fp.\u sock**#我们想稍后关闭“real”套接字 请求(url,标题) 尝试: fdurl=urllib2.urlopen(请求,超时=self.timeout) 除urllib2.URLError外,e: 打印“urlopen异常”,e realsock.close() fdurl.close()
修复程序很难看,但确实有效,不再有“太多打开的连接”。

可能重复@marcog我不认为这是同一个问题:-)另一个线程的用户问他是否应该关闭“连接”。我知道我应该关闭连接(我将关闭它:-),但如上所述,使用
close()
时,连接不会立即关闭。。。或者
contextlib.closing
(调用
close
)。好的,对不起,我的错。如果可以,我会收回投票。正如您所看到的
contextlib.closing
只使用
close()
。这也是我在上面的代码中手动执行的操作。所以问题仍然存在,第二次下载将失败,因为第一次连接没有使用
close()
.Hmmm立即关闭。我明白了,很抱歉我的回答。如果我设法解决了这个问题,我会通知您的。
urlopen
调用两次有什么好的原因吗?为什么在分配前使用
req
import socket
f.fp._sock.fp._sock.shutdown(socket.SHUT_RDWR)
fdurl = urllib2.urlopen(req,timeout=self.timeout) realsock = fdurl.fp._sock.fp._sock** # we want to close the "real" socket later req = urllib2.Request(url, header) try: fdurl = urllib2.urlopen(req,timeout=self.timeout) except urllib2.URLError,e: print "urlopen exception", e realsock.close() fdurl.close()