gpt4 book ai didi

python - 尝试在 Python 中列出 ftp 目录时出现 OSError

转载 作者:太空宇宙 更新时间:2023-11-04 09:54:04 24 4
gpt4 key购买 nike

使用 Python 3.6.3。

我正在连接到 FTP 以通过 FTP_TLS 使用 ftplib

ftps = ftplib.FTP_TLS('example.com', timeout=5)

# TLS is more secure than SSL
ftps.ssl_version = ssl.PROTOCOL_TLS

# login before securing control channel
ftps.login('username@example.com', 'password')

# switch to secure data connection
ftps.prot_p()

# Explicitly set Passive mode
ftps.set_pasv(True)

这一切都有效。我可以发送 ftps.mkd('mydir')(创建目录)和 ftps.cwd('mydir')(更改工作目录),两者都可以正常工作。

但是如果我发送任何这些(据我所知,它们基本上都是同义词):

        ftps.dir()
ftps.nlst()
ftps.retrlines('LIST')
ftps.retrlines('MLSD')

然后我返回一个异常(下面还包括所有 ftplib 调试信息;通常也与 FileZilla 显示的相匹配):

*cmd* 'AUTH TLS'
*put* 'AUTH TLS\r\n'
*get* '234 AUTH TLS OK.\n'
*resp* '234 AUTH TLS OK.'
*cmd* 'USER username@example.com'
*put* 'USER username@example.com\r\n'
*get* '331 User username@example.com OK. Password required\n'
*resp* '331 User username@example.com OK. Password required'
*cmd* 'PASS ******************************'
*put* 'PASS ******************************\r\n'
*get* '230 OK. Current restricted directory is /\n'
*resp* '230 OK. Current restricted directory is /'
*cmd* 'PBSZ 0'
*put* 'PBSZ 0\r\n'
*get* '200 PBSZ=0\n'
*resp* '200 PBSZ=0'
*cmd* 'PROT P'
*put* 'PROT P\r\n'
*get* '200 Data protection level set to "private"\n'
*resp* '200 Data protection level set to "private"'
*cmd* 'MKD mydir'
*put* 'MKD mydir\r\n'
*get* '257 "mydir" : The directory was successfully created\n'
*resp* '257 "mydir" : The directory was successfully created'
*cmd* 'CWD mydir'
*put* 'CWD mydir\r\n'
*get* '250 OK. Current directory is /mydir\n'
*resp* '250 OK. Current directory is /mydir'
*cmd* 'TYPE A'
*put* 'TYPE A\r\n'
*get* '200 TYPE is now ASCII\n'
*resp* '200 TYPE is now ASCII'
*cmd* 'PASV'
*put* 'PASV\r\n'
*get* '227 Entering Passive Mode (8,8,8,8,8,8)\n'
*resp* '227 Entering Passive Mode (8,8,8,8,8,8)'
*cmd* 'MLSD'
*put* 'MLSD\r\n'
*get* '150 Accepted data connection\n'
*resp* '150 Accepted data connection'
Traceback (most recent call last):
File "c:\my_script.py", line 384, in run_ftps
ftps.retrlines('MLSD')
File "c:\libs\Python36\lib\ftplib.py", line 485, in retrlines
conn.unwrap()
File "C:\libs\Python36\lib\ssl.py", line 1051, in unwrap
s = self._sslobj.unwrap()
File "C:\libs\Python36\lib\ssl.py", line 698, in unwrap
return self._sslobj.shutdown()
OSError: [Errno 0] Error

相同的 FTP 命令 (LIST) 通过 filezilla 工作正常。

我可以通过谷歌搜索找到的最接近的东西是:https://bugs.python.org/msg253161 - 我不确定它是否相关或相关。

简短版本:“OSError:[Errno 0] 错误”究竟是什么意思,我该如何列出我的目录内容?

编辑:问题似乎只发生在 FTP_TLS 上。它通过普通 FTP 连接工作正常,但我需要 FTP_TLS。

最佳答案

问题可能是 FTP 服务器要求新数据通道中的 TLS session 与控制 channel 相同。这在 Python 3.7 中尚未修复。子类 ftplib.FTP_TLS 在这里找到的解决方案 https://stackoverflow.com/a/43301750我做了一个小修复:

import ftplib
from ssl import SSLSocket


class ReusedSslSocket(SSLSocket):
def unwrap(self):
pass


class MyFTP_TLS(ftplib.FTP_TLS):
"""Explicit FTPS, with shared TLS session"""
def ntransfercmd(self, cmd, rest=None):
conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest)
if self._prot_p:
conn = self.context.wrap_socket(conn,
server_hostname=self.host,
session=self.sock.session) # reuses TLS session
conn.__class__ = ReusedSslSocket # we should not close reused ssl socket when file transfers finish
return conn, size

像这样使用它:

ftps = MyFTP_TLS('example.com', timeout=5)

关于python - 尝试在 Python 中列出 ftp 目录时出现 OSError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46633536/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com