我编写了一个 FTP 脚本,遗憾的是该脚本必须处理位于防火墙后面的服务器。 ISP 也会很早就切断我的控制连接,无论我在防火墙的任一侧设置什么样的超时设置。我最终做出了两个选择。 1) 在 retrbinary 命令中分叉代码,以便下载完成时每 n 秒发送一次“NOOP”,或者 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'