FTP文件传输期间Python数据通道超时

FTP文件传输期间Python数据通道超时,python,python-3.x,ftp,ftps,Python,Python 3.x,Ftp,Ftps,我正在尝试使用Python的ftplib传输文件 def ftps_put_file(host, user, password, ftp_file_path, processed_file): try: context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile='C:\\PATH\\TO\\SECURE.crt') with FTP_TLS(host, user=user, p

我正在尝试使用Python的
ftplib
传输文件

def ftps_put_file(host, user, password, ftp_file_path, processed_file):
    try:
        context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile='C:\\PATH\\TO\\SECURE.crt')
        with FTP_TLS(host, user=user, passwd=password, context=context, timeout=10) as connection, open(processed_file, 'rb') as read_file:
            connection.set_debuglevel(2)
            connection.prot_p()
            connection.cwd(ftp_file_path)
            connection.storbinary(f"STOR {processed_file.name}", read_file)
    except Exception as e:
        print('Error occured in transporter.ftps_put_file: ' + str(e))
我可以连接到FTP主机没有任何问题,但在文件传输过程中。连接超时开始并关闭连接,然后连接日志显示“425数据通道因未满足最低带宽要求而超时”。我使用过其他FTP客户端(Filezilla、WinSCP),两者都可以连接到主机

记录连接超时设置为2分钟的日志

*cmd* 'PBSZ 0'
*put* 'PBSZ 0\r\n'
*get* '200 PBSZ command successful.\n'
*resp* '200 PBSZ command successful.'
*cmd* 'PROT P'
*put* 'PROT P\r\n'
*get* '200 PROT command successful.\n'
*resp* '200 PROT command successful.'
*cmd* 'CWD /'
*put* 'CWD /\r\n'
*get* '250 CWD command successful.\n'
*resp* '250 CWD command successful.'
*cmd* 'TYPE I'
*put* 'TYPE I\r\n'
*get* '200 Type set to I.\n'
*resp* '200 Type set to I.'
*cmd* 'PASV'
*put* 'PASV\r\n'
*get* '227 Entering Passive Mode (204,58,62,196,19,199).\n'
*resp* '227 Entering Passive Mode (204,58,62,196,19,199).'
*cmd* 'STOR text.txt'
*put* 'STOR text.txt\r\n'
*get* '125 Data connection already open; Transfer starting.\n'
*resp* '125 Data connection already open; Transfer starting.'
*cmd* 'QUIT'
*put* 'QUIT\r\n'
*get* '425 Data channel timed out due to not meeting the minimum bandwidth requirement.\n'
*resp* '425 Data channel timed out due to not meeting the minimum bandwidth requirement.'
记录连接超时时间设置为60秒或更少的日志这个序列看起来很奇怪,因为连接退出后会导致
226传输完成
。它不应该声明传输已完成,然后退出吗

*cmd* 'PBSZ 0'
*put* 'PBSZ 0\r\n'
*get* '200 PBSZ command successful.\n'
*resp* '200 PBSZ command successful.'
*cmd* 'PROT P'
*put* 'PROT P\r\n'
*get* '200 PROT command successful.\n'
*resp* '200 PROT command successful.'
*cmd* 'CWD /'
*put* 'CWD /\r\n'
*get* '250 CWD command successful.\n'
*resp* '250 CWD command successful.'
*cmd* 'TYPE I'
*put* 'TYPE I\r\n'
*get* '200 Type set to I.\n'
*resp* '200 Type set to I.'
*cmd* 'PASV'
*put* 'PASV\r\n'
*get* '227 Entering Passive Mode (204,58,62,196,20,46).\n'
*resp* '227 Entering Passive Mode (204,58,62,196,20,46).'
*cmd* 'STOR text.txt'
*put* 'STOR text.txt\r\n'
*get* '125 Data connection already open; Transfer starting.\n'
*resp* '125 Data connection already open; Transfer starting.'
*cmd* 'QUIT'
*put* 'QUIT\r\n'
*get* '226 Transfer complete.\n'
*resp* '226 Transfer complete.'

我也遇到同样的问题。我调试通信的选项是有限的(不能完全访问客户机,不能访问服务器),但在我看来,当客户机关闭连接时,服务器端似乎没有发送确认(如下所述--)

我在客户端使用Linux Python 3.7标准库(ftplib.FTP_TLS),在服务器端使用Windows FTP服务

目前没有令人满意的解决方案,我只是通过检查上传的文件大小来确保文件正确上传。有人告诉我,Windows上的FileZilla客户端正确地处理了这一点(即没有错误,但我无法验证)。

如果您使用的是MS FTP(S)服务器,则存在一个黑客攻击,涉及在ftplib.py库中的storbinary函数中注释一些代码

当我在这个SO解决方案/黑客中看到这一点时,我也遇到了同样的问题。谢天谢地,它对我有用

基本上,你只需要确保你没有打电话给conn.unwrap

lib/ftplib.py

#shutdown ssl layer
if isinstance(conn, ssl.SSLSocket):
    pass #conn.unwrap()

哇!谢谢你花时间帮我做这件事。没想到会找到写WinSCP的人。这里有一个指向WinSCP日志的链接。我混淆了一些东西,但我想你会明白的。我只在将连接超时设置为2分钟时注意到425错误(发生这种情况时不会传输任何内容)。如果超时设置为60秒或更短,则传输成功,但连接仍会抛出错误,并且日志序列看起来很奇怪(请参见编辑)。当超时时间为一分钟或更短时,它将被传输。奇怪的是,连接仍然抛出错误。