【问题标题】:Upload file to FTP server via FTP_TLS get error ssl通过 FTP_TLS 将文件上传到 FTP 服务器获取错误 ssl
【发布时间】:2017-12-04 04:24:20
【问题描述】:

我使用 filezilla 服务器来创建 ftp 服务器。 ssl 选项在端口 21 和 990 上打开。我尝试使用 filezilla 客户端上传和下载文件仍然运行良好。我尝试使用 ftplib 将文件上传到 FTP 服务器。这是我的代码:

from ftplib import FTP_TLS, FTP
import socket
import ssl

file = open('test.py','rb')

ftps = FTP_TLS()
ftps.set_debuglevel(2)
s = ftps.connect(host='192.168.1.102', port=21)
ftps.login(user="xxx", passwd="xxxxxx")
ftps.prot_p()
ftps.storbinary("STOR test.py", file)

并得到错误:

*get* '227 Entering Passive Mode (192,168,1,102,19,170)\r\n'
*resp* '227 Entering Passive Mode (192,168,1,102,19,170)'
*cmd* 'STOR test.py'
*put* 'STOR test.py\r\n'
*get* '150 Opening data channel for file upload to server of "/test.py"\r\n'
*resp* '150 Opening data channel for file upload to server of "/test.py"'
Traceback (most recent call last):
  File "ImplicitFTP.py", line 49, in <module>
    ftps.storbinary("STOR test.py", file)
  File "C:\Python27\lib\ftplib.py", line 760, in storbinary
    conn = self.transfercmd(cmd, rest)
  File "C:\Python27\lib\ftplib.py", line 376, in transfercmd
    return self.ntransfercmd(cmd, rest)[0]
  File "C:\Python27\lib\ftplib.py", line 713, in ntransfercmd
    server_hostname=self.host)
  File "C:\Python27\lib\ssl.py", line 363, in wrap_socket
    _context=self)
  File "C:\Python27\lib\ssl.py", line 611, in __init__
    self.do_handshake()
  File "C:\Python27\lib\ssl.py", line 840, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:661)

请帮助我。谢谢

【问题讨论】:

  • several similar posts。此问题可能有多种原因,但您没有提供足够的信息来进一步挖掘。请检查现有帖子以了解您的问题的可能解决方案。如果没有找到,请提供有关如何在您的特定情况下重现问题的足够详细信息,即 Python 版本、OpenSSL 并授予访问此特定服务器或显示相同问题的另一台服务器的权限。
  • 服务器端日志也会有所帮助。

标签: python ssl ftp


【解决方案1】:

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

import ftplib


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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    • 2011-04-06
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    相关资源
    最近更新 更多