我有一个多线程FTP脚本。当数据套接字正在接收数据时,一个线程循环向控制套接字发送NOOP命令,以在大型传输期间保持控制连接活动状态。
如果我想保持控制连接处于活动状态,我无法使用FTP.retrbinary()命令,因为我必须分离数据和控制套接字,而retrbinary不会这样做。
下面是代码:
如果我想保持控制连接处于活动状态,我无法使用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 传输,而我正在传输视频,因此必须使用二进制传输(因此调用ftp.voidcmd('TYPE I')
以强制二进制模式)。
如果我不调用ftp.voidcmd('TYPE I')
,则 NOOP 命令会成功发送,并且输出如下:
*cmd* 'NOOP'
*put* 'NOOP\r\n'
*get* '200 NOOP: data transfer in progress\n'
*resp* '200 NOOP: data transfer in progress'
*cmd* 'NOOP'
*put* 'NOOP\r\n'
*get* '200 NOOP: data transfer in progress\n'
*resp* '200 NOOP: data transfer in progress'
*cmd* 'NOOP'
*put* 'NOOP\r\n'
*get* '200 NOOP: data transfer in progress\n'
*resp* '200 NOOP: data transfer in progress'
等等,该文件是ASCII格式的,因此已经损坏。如果我确实调用ftp.voidcmd('TYPE I')
,那么NOOP命令只会发送一次,并且控制套接字直到传输完成才会响应。如果文件很大,则控制套接字会超时,就像从未发送过NOOP一样...
非常奇怪,但我确定它很简单。似乎transfercmd()
没有按照预期拆分控制和数据套接字...因此ftp变量与数据流未分离...或者其他奇怪的事情。
感谢您提供的任何建议。
FTP.retrbinary()
代替同时使用FTP.voidcmd(TYPE I)
和FTP.transfercmd()
? - uselpatcpdump
和/或strace
来缩小问题范围。看到在响应NOOP
时出现 "数据传输正在进行中",我有点惊讶,也许这是ftplib
的一个特殊情况。 - Dima Tisnekpycurl
。 - Dima Tisnek