簡體   English   中英

ftplib - 文件創建速度非常慢:SSLError:讀取操作超時

[英]ftplib - file creation very slow: SSLError: The read operation timed out

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

我不明白為什么它這么慢以及為什么它會超時,即使它創建了那個文件。

PS請詢問我是否需要提供其他信息

更新我也嘗試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 有點慢。 不過我想這樣的小文件應該比這處理得快得多。

Update2那是一些奇怪的 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_TLSprot_p和 Microsoft FTP 服務器時,我在 STORBINARY 函數上遇到了這個問題。

例子:

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

錯誤表明 unwrap 函數超時。

它與以下問題有關:

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_lib\\my_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__方法來確認這一點)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM