6

更新#1

问题中的代码对于稳定连接(如本地网络或 Intranet)非常有效。

更新#2

FTPClient用 ftplib 实现了这个类,它可以:

  1. 监控下载进度
  2. 在超时或断开连接的情况下重新连接
  3. 多次尝试下载文件
  4. 显示当前下载速度。

重新连接后,它会从断开点继续下载过程(如果 FTP 服务器支持它)。有关详细信息,请参阅下面的我的答案。


问题

我必须在 python 上实现任务,每天通过 FTP 下载一堆大文件(每个文件 0.3-1.5Gb * 200-300 个文件),然后对文件进行一些处理。我是通过 ftplib 完成的。但有时它会挂起,并且无法完成某些文件的下载。为了解决这个问题,我开始使用 KEEPALIVE 设置,但我仍然没有收到好的结果

with closing(ftplib.FTP()) as ftp:
    try:
        ftp.connect(self.host, self.port, 30*60) #30 mins timeout
        # print ftp.getwelcome()
        ftp.login(self.login, self.passwd)
        ftp.set_pasv(True)
        ftp.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
        ftp.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 75)
        ftp.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60)
        with open(local_filename, 'w+b') as f:
            res = ftp.retrbinary('RETR %s' % orig_filename, f.write)

            if not res.startswith('226 Transfer complete'):
                logging.error('Downloaded of file {0} is not compile.'.format(orig_filename))
                os.remove(local_filename)
                return None

        os.rename(local_filename, self.storage + filename + file_ext)
        ftp.rename(orig_filename, orig_filename + '.copied')

        return filename + file_ext

    except:
            logging.exception('Error during download from FTP')

细节

  • 通常下载一个文件需要 7-15 分钟。
  • FTP 服务器总是在日志中显示文件已完全下载,但客户端部分挂起。不是每次,而是偶尔。

问题

  • 可能是因为断线?
  • 如何为下载过程实施监视器并在断开连接时重新连接
4

1 回答 1

12

因为找不到任何好的建议或代码示例,我实现了自己的解决方案。非常感谢 Stackoverflow 社区为我在代码中使用的一些想法。由于代码的大小(约 120 行) ,我将代码放到了 GitHub(pyFTPclient)。

我在劣质网络(包括 3G 移动互联网)上测试了该解决方案,它对我来说工作正常。但当然它可能有一些错误。

我将不胜感激任何意见或建议。先感谢您。

于 2013-10-18T19:11:23.017 回答