栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Python:ftplib在传输结束时挂起

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python:ftplib在传输结束时挂起

没有更多信息,我实际上无法调试您的问题,因此我只能提出最一般的答案。这可能对您来说不是必需的,但对任何人来说都足够了。

retrbinary
将阻塞直到整个文件完成。如果超过5分钟,则整个5分钟内都不会在控制通道上发送任何消息。您的客户端正在超时控制通道,或者服务器正在超时。因此,当您尝试与挂断时
ftp.quit()
,它将永远挂起或引发异常。

您可以使用构造

timeout
函数上的参数来控制一方的超时
FTP
。某些服务器支持
IDLE
命令,以允许您设置服务器端超时。但是,即使事实证明适当的超时也是可行的,您如何首先选择适当的超时时间呢?

您真正想做的是防止数据套接字上发生传输时控制套接字超时。但是如何?例如,如果您

ftp.voidcmd('NOOP')
经常在回调函数中使用它,就足以保持连接正常运行……但是这也将迫使您阻塞直到服务器响应
NOOP
,许多服务器在数据传输之前不会这样做已经完成,这意味着您将永远永久阻塞(或直到另一个超时),而不会获取数据。

处理两个套接字而一个不阻塞另一个套接字的标准技术是类似

select.select
或的多路复用器。您可以在此处执行此操作,但是您将不得不放弃使用简单的
retrbinary
接口,而是使用
transfercmd
显式获取数据套接字。

例如:

def downloadFile(…):    ftp = FTP(…)    sock = ftp.transfercmd('RETR ' + filename)    def background():        f = open(…)        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(60)        ftp.voidcmd('NOOP')

另一种解决方案是一次读取20MB,然后调用

ftp.abort()
,并使用
rest
参数恢复每个新
retrbinary
文件的传输,直到到达文件末尾。但是,这样
ABOR
可能会永远挂起
NOOP
,因此并不能保证任何事情,更不用说服务器不必对此做出响应了。

可以
做的就是关闭整个连接(不是

quit
,而是
close
)。这对服务器来说不是很好,并且可能导致重新发送一些浪费的数据,并且如果过快地杀死套接字,还可能阻止TCP正常加速到全速运行。但它应该工作。

请查看此答案-并注意,它需要针对特定​​的故障服务器进行一些测试,以找出哪些变体可以正确,有效地工作。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/626019.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号