[英]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_TLS
、 prot_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
解決:
打開 ftplib 的 python 頁面: https ://docs.python.org/3/library/ftplib.html
單擊源代碼,它將帶您進入如下內容: https ://github.com/python/cpython/blob/3.10/Lib/ftplib.py
將此代碼的副本創建到您的項目中(例如: my_lib\\my_ftplib.py
)
對於失敗的方法,在您的情況下是 STORBINARY,錯誤看起來在該方法中顯示conn.unwrap()
的行上。 評論這一行。 輸入關鍵字pass
否則空的if
塊將給出語法錯誤。
在您要實例化 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.