残念ながら、ファイアウォールの背後にあるサーバーを処理する必要があるFTPスクリプトを作成しました。また、ファイアウォールのいずれかの側にどのような種類のタイムアウト設定を設定しても、ISPは制御接続をかなり早期に切断します。私はついに2つの選択肢にたどり着きました。1)ダウンロードの完了中に「NOOP」がn秒ごとに送信されるようにretrbinaryコマンドでコードをフォークするか、2)スクリプトがローカルファイルのサイズとリモートファイルのサイズを比較するようにretrbinaryコマンドでコードをフォークします。サイズが異なると、次のファイルのダウンロードを試みます。
n秒ごとに「NOOP」を送信する試みを例示するコードを以下に含めました。問題は、スクリプトがisAlive whileループに到達し、ftp.sendcmd('NOOP')を実行すると、処理がハングし、whileループがロックされることです。ファイルはまだTCPポート63xxxにダウンロードされていますが、ポート21の制御接続がロックされています。
スレッドを使用してダウンロード中にファイルサイズを確認する限り、ファイルサイズが完全な値に完全に到達せず、ダウンロードの最後に同じ値にとどまっていたため、失敗しました。
現在の主な問題は、大量のダウンロードを通じて、制御接続を維持することです。何らかの理由で制御接続が切断された場合、ファイル転送がいつ終了したかを知るための適切な方法がスクリプトに必要です。制御接続がないと、サーバーの応答から知る方法がありません。
前もって感謝します。
def FTP_RETR(ftp_transfer_path, f, start_byte):
ftp.retrbinary('RETR %s' % ftp_transfer_path, f.write, rest = '%s' % start_byte)
f.close()
ftp = FTP()
ftp.connect(FTP_server, FTP_port)
ftp.login(FTP_username, FTP_password)
ftp.cwd(home_dir)
ftp_transfer_path = 'file_to_get.dat'
start_byte = 0
filename = 'C:\\myfile.txt'
f = open('C:\\myfile.txt', 'wb')
ftp.sendcmd('TYPE I')
transfer_thread = threading.Thread(target = FTP_RETR, args = (ftp_transfer_path, f, start_byte))
transfer_thread.start()
while transfer_thread.isAlive():
time.sleep(5)
ftp.sendcmd('NOOP')
print 'Finished'