Python FTP 套接字超时处理



我在处理python35 ftplib的套接字超时时遇到问题。当发生套接字超时错误时,由于某种原因我无法捕获异常,并且脚本仍然引发错误并退出。以下是相关的代码块:

try:
ftp = FTP(self.config.base_url, timeout=400)
ftp.login()
ftp.cwd(self.config.root_path)
ftp.retrbinary("RETR {0}".format(os.path.join(self.root_path, file_path)), fp.write, 1024)
ftp.quit()
except socket.timeout:
self.download_file(file_path)

由于某种原因,此脚本仍然会因套接字超时异常而出错,这怎么可能?一般的包罗万象也行不通。以下是错误的堆栈跟踪:

File "ftp.py", line 82, in __init__
self.ftp = FTP(self.config.base_url, timeout=400)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ftplib.py", line 118, in __init__
self.connect(host)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ftplib.py", line 156, in connect
self.welcome = self.getresp()
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ftplib.py", line 235, in getresp
resp = self.getmultiline()
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ftplib.py", line 221, in getmultiline
line = self.getline()
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ftplib.py", line 203, in getline
line = self.file.readline(self.maxline + 1)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/socket.py", line 576, in readinto
return self._sock.recv_into(b)
socket.timeout: timed out

如您所见,这是抛出的socket.timeout错误,那么如何不捕获呢?经过几个小时的互联网研究,我无法找到有关如何解决此问题的任何有用信息,对此问题的任何见解将不胜感激。

作为参考,以下是 socket.py 的相关代码块:

def readinto(self, b):
"""Read up to len(b) bytes into the writable buffer *b* and return
the number of bytes read.  If the socket is non-blocking and no bytes
are available, None is returned.
If *b* is non-empty, a 0 return value indicates that the connection
was shutdown at the other end.
"""
self._checkClosed()
self._checkReadable()
if self._timeout_occurred:
raise OSError("cannot read from timed out object")
while True:
try:
return self._sock.recv_into(b)
except timeout:
self._timeout_occurred = True
raise
except error as e:
if e.args[0] in _blocking_errnos:
return None
raise

更新: 似乎问题是,如果传递给 FTP 构造函数的超时大于套接字超时的默认值,ftplib 的行为会出乎意料。在此编辑时,有一个未解决的 python 问题来解决此行为:http://bugs.python.org/issue30956

尝试添加

ftp.set_pasv(假(

禁用被动模式它应该可以工作

最新更新