python - 关闭 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 = 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.>

所以第一个文件被加载,第二个失败,因为第一个连接没有关闭。

但是当我在 f.close() 之后使用 sleep(1) 时,错误不会发生:

loaded 463675266
loaded 463675266

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

最佳答案

原因确实是文件描述符泄漏。我们还发现,使用 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()

修复很丑陋,但可以解决问题,不再有“太多打开的连接”。

关于python - 关闭 urllib2 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5442291/

相关文章:

具有函数计数器变量的 Python 装饰器类

python - @cached_property 和@lru_cache 装饰器的区别

python - 是否可以将 Flask 中的 "app factory"模式用于 Click CLI 应用程序?

python - Pyyaml 嵌套对象

iis - Azure 网站上的自定义 404

javascript - Webgl FTP错误

java - 使用 commons net 3.0 api (org.apache.commons.net ) 在 ftp 服务器上上传文件时出现问题

c# - 有什么办法可以改善 TCP 连接时间吗?

web-services - 我想连接我的服务

java - Oracle DB 是否支持每个连接的多个(并行)操作?