我编写了一个 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'