我有一个线程化的FTP脚本。当数据套接字接收数据时,线程循环将NOOP命令发送到控制套接字,以在大型传输期间保持控制连接的活动状态。在
我不能使用FTP.retrbinary()
命令,因为如果我想保持控制连接的有效性,我必须分离数据和控制套接字,而retrbinary
没有这样做。在
代码如下:
def downloadFile(filename, folder):
myhost = 'HOST'
myuser = 'USER'
passw = 'PASS'
#login
ftp = FTP(myhost,myuser,passw)
ftp.set_debuglevel(2)
ftp.voidcmd('TYPE I')
sock = ftp.transfercmd('RETR ' + filename)
def background():
f = open(folder + filename, 'wb')
while True:
block = sock.recv(1024*1024)
if not block:
break
f.write(block)
sock.close()
t = threading.Thread(target=background)
t.start()
while t.is_alive():
t.join(120)
ftp.voidcmd('NOOP')
ftp.quit();
我的问题:FTP.transfercmd("RETR " + filename)
默认为ASCII传输和Im传输视频,因此它必须是二进制的(因此ftp.voidcmd('TYPE I)
调用强制二进制模式)。在
如果IDONT调用ftp.voidcmd('TYPE I)
,NOOP命令成功发送,输出如下:
但是文件是ASCII格式的,因此被破坏了。如果IDOcallftp.voidcmd('TYPE I)
,NOOP命令只发送一次,并且控制套接字在传输完成之前不会响应。如果文件很大,控制套接字将超时,好像从未发送noop一样。。。在
很奇怪,但我相信很简单。似乎transfercmd()
并没有像预期的那样分割控件和数据套接字。。。因此ftp变量没有从数据流中分离出来。。。或者别的什么。奇怪。在
提前感谢您提供的任何建议。在
tcpdump
确认服务器只在服务器发送整个文件之后发送226 Transfer complete.
。在我怀疑这是FTP规范的一部分。在
实际上,看看
^{1}$retrbinary
中的retrbinary
代码:最后一行预期只有在传输完成后才能得到传输结果(服务器知道)。在
实际上,您的代码似乎缺少
voidresp()
位。在我对ftp不是很熟悉,从我所看到的后台下载程序中,
lftp
实际上为每次并行下载打开新的控制连接。在如果你的文件真的很大,你就有了一个合理的顾虑。在
FTP有很多扩展,可能有一些东西可以满足您的需要。在
或者,您可以制作如下循环:
^{pr2}$相关问题 更多 >
编程相关推荐