以下是我用于通过ftp下载的一些代码。我试图停止下载然后继续或之后重新下载。我试过ftp.abort()但它只挂起并返回超时。
ftplib.error_proto: 421 Data timeout. Reconnect. Sorry.
情景: 方案是用户将选择要下载的文件,在下载时,用户可以停止当前下载并下载新文件。代码'if os.path.getsize(self.file_path)> 117625:'只是我的例子,如果用户停止下载。它不是文件的完整大小。
感谢。
from ftplib import FTP
class ftpness:
def __init__(self):
self.connect(myhost, myusername, mypassword)
def handleDownload(self,block):
self.f.write(block)
if os.path.getsize(self.file_path) >117625:
self.ftp.abort()
def connect(self,host, username, password):
self.ftp = FTP(host)
self.ftp.login(username, password)
self.get(self.file_path)
def get(self,filename):
self.f = open(filename, 'wb')
self.ftp.retrbinary('RETR ' + filename, self.handleDownload)
self.f.close()
self.ftp.close
a = ftpness()
答案 0 :(得分:0)
错误421是std超时错误。所以需要连接才能下载文件。
def handleDownload(self,block):
self.f.write(block)
if os.path.getsize(self.file_path) >117625:
self.ftp.abort()
else:
self.ftp.sendcmd('NOOP')
#try to add this line just to keep the connection alive.
希望这会对你有所帮助。 :)
答案 1 :(得分:0)
这是一种使用看门狗计时器的方法。这涉及创建一个单独的线程,这取决于您的应用程序的设计可能是不可接受的。
要使用用户事件终止下载,它的想法是一样的。如果GUI在单独的线程中工作,那么该线程可以直接到达FTP
实例内部并直接关闭其套接字。
from threading import Timer
class ftpness:
...
def connect(self,host, username, password):
self.ftp = FTP(host)
self.ftp.login(username, password)
watchdog = Timer(self.timeout, self.ftp.sock.close)
watchdog.start()
self.get(self.file_path)
watchdog.cancel() # if file transfer succeeds cancel timer
这样,如果文件传输的运行时间超过预设超时,则计时器线程将关闭传输下方的套接字,强制get
调用引发异常。只有当传输成功时才会取消看门狗定时器。
虽然这与您的问题无关,但通常connect
调用不应传输有效负载数据。
答案 2 :(得分:0)
这是你的会话空闲时间太长。你可以在总统之后提交实例化ftplib。除此以外。修改ftp软件配置。
例如,您使用vsftpd,您可以将以下配置添加到vsftpd.conf:
idle_session_timeout=60000 # The default is 600 seconds