ftplib - file creation very slow: SSLError:读取操作超时


import ftplib
import csv
import StringIO
sio = StringIO.StringIO()
data = csv.writer(sio)
data.writerows(data_to_export)
sio.seek(0)
ftps.storbinary("STOR " + 'blah.csv', sio)
ftps.close()

所以我创建的文件只有56行,它创建得很慢。当它完成创建时,我得到这个错误:

    ftps.storbinary("STOR " + 'blah.csv', sio)
  File "/usr/lib/python2.7/ftplib.py", line 752, in storbinary
    conn.unwrap()
  File "/usr/lib/python2.7/ssl.py", line 384, in unwrap
    s = self._sslobj.shutdown()
SSLError: The read operation timed out

我不明白为什么它这么慢,为什么它会超时,即使它创建了那个文件。

注:请询问我是否需要提供额外的信息

我也尝试过cString,但它并没有改善任何东西,因为我猜它与写作速度无关。

如果存在差异,则使用隐式SSL/TLS模式连接ftp (ftp不支持显式SSL/TLS)。

更深入的研究。这就是调试ftp的结果:

*cmd* 'TYPE I'
*resp* '200 Binary mode selected.'
*cmd* 'PASV'
*resp* '227 Entering Passive Mode (*,*,*,*,*,*)'
*cmd* 'STOR blah.csv'
*resp* '125 Secure data connection open; transfer starting.'

然后停留在最后一个输出,直到连接超时。

注意。我的网络连接很好,但是那个ftp有点慢。不过我想这么小的文件应该处理得比这快得多。

更新2 这是一个奇怪的ftp。尝试不安全的ftp连接,文件上传正确和快速。这种隐式连接与这种缓慢的性能和超时有关。

关于速度,有太多的因素要猜测,所以我会调整代码并尝试下面的代码,我最近为客户ftp交付创建的,可以声明它的工作没有错误。

注意,这是来自一个更大的文件,但已经提取了相关的部分,所以忽略一些变量,如args。Var,你可能需要根据带宽等来调整块大小,尝试将其降低到1024,然后再向上工作。

希望有帮助

def initiate_ftp_connection(ftp_host, user, passwd, ftp_dir):
    ftp_session = ftplib.FTP()
    ftp_session.connect(ftp_host, 21)
    #uncomment for debugging.
    #ftp_session.set_debuglevel(2)
    ftp_session.login(user=user, 
                      passwd=passwd)
    #cd to correct remote directory
    ftp_session.cwd(ftp_dir)
    return ftp_session

def upload_deliverables(session, file_and_path):
    working_dir = os.path.dirname(file_and_path)
    #strip to remove any newlines
    filename = os.path.basename(file_and_path).strip()
    totalSize = os.path.getsize(file_and_path)
    #instantiate progress tracker for status updates
    uploadTracker = FtpUploadTracker(int(totalSize),filename)
    #change dir to working_dir
    os.chdir(working_dir)
    '''
     Trigger the ftp upload (storbinary) for the deliverable.
      Args:
       1: FTP KEYWORD and FILE
       2: File IO
       3: Blocksize
       4: Callback
    '''
    session.storbinary('STOR ' + filename, 
                        open(filename,'r'), 
                        8192, 
                        uploadTracker.ftp_callback)

#connect to server
ftp_session = initiate_ftp_connection(args.ftp_host, 
                                      args.ftp_user, 
                                      args.ftp_pass,
                                      args.ftp_dir)
#start ftp delivery
upload_deliverables(ftp_session, args.asset)
#quit the ftp session
ftp_session.quit()   
#close any file handles.
ftp_session.close()

我在使用python的ftplib.FTP_TLS, prot_p和Microsoft FTP服务器时遇到了STORBINARY函数的问题。

的例子:

ftps = FTP_TLS(host,username,password)
ftps.prot_p
STORBINARY...

错误指示打开函数超时。

这与以下问题有关:

https://www.sami-lehtinen.net/blog/python-32-ms-ftps-ssl-tls-lockup-fix

https://bugs.python.org/issue10808

https://bugs.python.org/issue34557

决定

:

  1. 打开ftplib的python页面:https://docs.python.org/3/library/ftplib.html

  2. 点击源代码,它会带你到类似这样的地方:https://github.com/python/cpython/blob/3.10/Lib/ftplib.py

  3. 创建此代码的副本到您的项目中(示例:my_libmy_ftplib.py)

  4. 对于失败的方法,在您的情况下STORBINARY,错误看起来在该方法中表示conn.unwrap()的行上。注释这一行。输入关键字pass,否则空if块会导致语法错误。

  5. 在实例化FTP_TLS的文件中导入上述库。现在您将不会再遇到此错误。

推理:函数def ntransfercmd中的代码(在FTP_LTS类下)将conn对象封装到SSL会话中。上面您所评论的代码行负责在传输后拆除SSL会话。由于某种原因,当使用Microsoft的FTP服务器时,代码在那一行被阻塞并导致超时。这可能是因为服务器在传输后断开了连接,也可能是因为服务器从自己的角度打开了SSL。我不确定。注释这一行是无害的,因为最终连接无论如何都会关闭——详细信息见下文:

在ftplib的python代码中,您将注意到STORBINARY函数中的conn对象被包含在with块中,并且它是使用socket.create_connection创建的。这意味着当代码退出with块时,会自动调用.close()(您可以通过查看python套接字类源代码中的__exit__方法来确认这一点)。

相关内容

  • 没有找到相关文章

最新更新