更新 #1
問題のコードは、安定した接続(ローカル ネットワークやイントラネットなど)に適しています。
更新 #2
FTPClient
次のことができる ftplib を使用してクラスを実装しました。
- ダウンロードの進行状況を監視する
- タイムアウトまたは切断の場合に再接続する
- ファイルのダウンロードを数回試行します
- 現在のダウンロード速度を表示します。
再接続後、切断ポイントからダウンロード プロセスを続行します (FTP サーバーがサポートしている場合)。詳細については、以下の私の回答を参照してください。
質問
FTP経由で大量の大きなファイル(ファイルあたり0.3〜1.5Gb * 200〜300ファイル)を毎日ダウンロードし、ファイルを処理するタスクをpythonに実装する必要があります。私は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 サーバーは、ファイルが完全にダウンロードされていることを常にログに示していますが、クライアント部分はハングしています。毎回ではありませんが、時々です。
質問
- 切断のせいでしょうか?
- ダウンロードプロセスのモニターを実装し、切断された場合に再接続する方法