0

这是我用来通过 ftp 下载的一些代码。我试图停止下载然后继续或之后重新下载。我试过 ftp.abort() 但它只会挂起并返回超时。

ftplib.error_proto: 421 Data timeout. Reconnect. Sorry.

SCENARIO: 场景是用户选择要下载的文件,在下载时,用户可以停止当前下载并下载一个新文件。如果用户停止下载,代码 '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()
4

3 回答 3

0

这是您的会话空闲时间太长。您可以在会长文件后进入实例化 ftplib。否则。修改ftp软件配置。

比如你使用vsftpd,可以在vsftpd.conf中加入如下配置:

idle_session_timeout=60000 # The default is 600 seconds

于 2013-09-17T11:10:05.597 回答
0

错误 421 是标准超时错误。所以需要在文件下载之前建立连接。

 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.

希望这会帮助你。:)

于 2012-04-09T13:21:34.613 回答
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调用不应传输有效负载数据。

于 2012-04-09T15:07:03.973 回答