Skip to main content
 首页 » 编程设计

python之如何在 Twisted 中对 FTP 命令进行排队

2025年05月04日13傻小

我正在使用 Twisted 编写一个 FTP 客户端,它会下载大量文件,而且我正在尝试以非常智能的方式进行。但是,我遇到的问题是我会非常快速地下载几个文件(有时每批约 20 个,有时约 250 个),然后下载会挂起,最终连接超时,然后开始下载和挂起再来一遍。我使用 DeferredSemaphore 一次只下载 3 个文件,但我现在怀疑这可能不是避免服务器节流的正确方法。

这里是有问题的代码:

def downloadFiles(self, result, directory): 
    # make download directory if it doesn't already exist 
    if not os.path.exists(directory['filename']): 
        os.makedirs(directory['filename']) 
 
    log.msg("Downloading files in %r..." % directory['filename']) 
 
    files = filterFiles(None, self.fileListProtocol) 
    # from http://stackoverflow.com/questions/2861858/queue-remote-calls-to-a-python-twisted-perspective-broker/2862440#2862440 
    # use a DeferredSemaphore to limit the number of files downloaded simultaneously from the directory to 3 
    sem = DeferredSemaphore(3) 
    jobs = [sem.run(self.downloadFile, f, directory) for f in files] 
    d = gatherResults(jobs) 
    return d 
 
def downloadFile(self, f, directory): 
    filename = os.path.join(directory['filename'], f['filename']).encode('ascii') 
    log.msg('Downloading %r...' % filename) 
    d = self.ftpClient.retrieveFile(filename, FTPFile(filename)) 
    return d 

您会注意到我正在重用 FTP 连接(顺便说一句,事件的)并使用我自己的 FTPFile 实例来确保在文件下载连接“丢失”(即完成)时关闭本地文件对象.看着FTPClient我想知道我是否应该使用 queueCommand直接地。老实说,我迷路了 retrieveFile命令 _openDataConnection甚至更多,所以也许它已经在使用了。

有什么建议吗?谢谢!

请您参考如下方法:

我建议使用 queueCommand,正如您所建议的那样,我怀疑您正在使用的信号量可能会导致您出现问题。我相信使用 queueCommand 会将您的 FTPClient 限制为单个事件连接(尽管我只是在推测),因此如果您想快速执行操作,您可能需要考虑创建一些 FTPClient 实例并将下载作业传递给它们。如果你使用 queueStringCommand ,你会得到一个 Deferred,你可以用它来确定每个客户端的位置,甚至可以在回调中为该客户端添加另一个作业到队列中。