我有一个Python3程序,该程序正在使用ftplib
上传大量文件。
它可以正常工作,但偶尔会在上传的随机点期间抛出以下例外:
[WinError 10013] An attempt was made to access a socket in a way forbidden by its access permissions
Traceback (most recent call last):
File "bulk_box_ftp.py", line 90, in push_folder_contents
placeFiles(ftp_conn, folder)
File "bulk_box_ftp.py", line 68, in placeFiles
placeFiles(ftp, localpath)
File "bulk_box_ftp.py", line 52, in placeFiles
ftp.storbinary('STOR ' + name, upfile)
File "...PythonPython36-32libftplib.py", line 503, in storbinary
self.voidcmd('TYPE I')
File "...PythonPython36-32libftplib.py", line 278, in voidcmd
return self.voidresp()
File "...PythonPython36-32libftplib.py", line 251, in voidresp
resp = self.getresp()
File "...PythonPython36-32libftplib.py", line 236, in getresp
resp = self.getmultiline()
File "...ProgramsPythonPython36-32libftplib.py", line 222, in getmultiline
line = self.getline()
File "...PythonPython36-32libftplib.py", line 204, in getline
line = self.file.readline(self.maxline + 1)
File "...PythonPython36-32libsocket.py", line 586, in readinto
return self._sock.recv_into(b)
File "...PythonPython36-32libssl.py", line 1009, in recv_into
return self.read(nbytes, buffer)
File "...PythonPython36-32libssl.py", line 871, in read
return self._sslobj.read(len, buffer)
File "...PythonPython36-32libssl.py", line 631, in read
v = self._sslobj.read(len, buffer)
OSError: [WinError 10013] An attempt was made to access a socket in a way forbidden by its access permissions
遵循此OSError
,队列中的所有其他文件将扔一个ConnectionResetError
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
什么可能导致这种例外?有什么办法可以安全地抓住它并恢复以继续FTP操作?
经过一定的反复试验和错误,我发现FTP连接必须预先完整重置。我将所有FTP上传代码包装在try:
块中,并在抬高OSError
时捕获:
except OSError as e:
print("FTP Connection Error Occurred")
attempt_conn_reset(current_pwd)
此功能将终止并重新建立FTP连接:
def attempt_conn_reset(pwd="/"):
# resets the FTP connection in case of a socket disconnect
print("Attempting FTP reconnect")
try:
ftp_conn.quit()
except ConnectionResetError:
print("Connection was already closed")
# allow OS to release port
time.sleep(2)
ftp_conn.connect(FTP_URL)
ftp_conn.login(FTP_USER, FTP_PASSWORD)
ftp_conn.prot_p()
ftp_conn.cwd(pwd)
print("FTP connection has been reset")