2017-10-08 170 views
0

使用Python 3.6.3。嘗試使用Python列出FTP目錄時出現OSError

我正在通過FTP_TLS連接到FTP以使用ftplib

ftps = ftplib.FTP_TLS('example.com', timeout=5) 

# TLS is more secure than SSL 
ftps.ssl_version = ssl.PROTOCOL_TLS 

# login before securing control channel 
ftps.login('[email protected]', 'password') 

# switch to secure data connection 
ftps.prot_p() 

# Explicitly set Passive mode 
ftps.set_pasv(True) 

這一切都有效。我可以發送ftps.mkd('mydir')(make目錄)和ftps.cwd('mydir')(更改工作目錄),並且都可以正常工作。

但是,如果我送其中任何(他們基本上都同義詞,據我可以告訴):

 ftps.dir() 
     ftps.nlst() 
     ftps.retrlines('LIST') 
     ftps.retrlines('MLSD') 

然後我得到一個異常(以下還包括所有FTPLIB調試信息作爲還有,一般有什麼FileZilla中也表示相匹配):

*cmd* 'AUTH TLS' 
*put* 'AUTH TLS\r\n' 
*get* '234 AUTH TLS OK.\n' 
*resp* '234 AUTH TLS OK.' 
*cmd* 'USER [email protected]' 
*put* 'USER [email protected]\r\n' 
*get* '331 User [email protected] OK. Password required\n' 
*resp* '331 User [email protected] OK. Password required' 
*cmd* 'PASS ******************************' 
*put* 'PASS ******************************\r\n' 
*get* '230 OK. Current restricted directory is /\n' 
*resp* '230 OK. Current restricted directory is /' 
*cmd* 'PBSZ 0' 
*put* 'PBSZ 0\r\n' 
*get* '200 PBSZ=0\n' 
*resp* '200 PBSZ=0' 
*cmd* 'PROT P' 
*put* 'PROT P\r\n' 
*get* '200 Data protection level set to "private"\n' 
*resp* '200 Data protection level set to "private"' 
*cmd* 'MKD mydir' 
*put* 'MKD mydir\r\n' 
*get* '257 "mydir" : The directory was successfully created\n' 
*resp* '257 "mydir" : The directory was successfully created' 
*cmd* 'CWD mydir' 
*put* 'CWD mydir\r\n' 
*get* '250 OK. Current directory is /mydir\n' 
*resp* '250 OK. Current directory is /mydir' 
*cmd* 'TYPE A' 
*put* 'TYPE A\r\n' 
*get* '200 TYPE is now ASCII\n' 
*resp* '200 TYPE is now ASCII' 
*cmd* 'PASV' 
*put* 'PASV\r\n' 
*get* '227 Entering Passive Mode (8,8,8,8,8,8)\n' 
*resp* '227 Entering Passive Mode (8,8,8,8,8,8)' 
*cmd* 'MLSD' 
*put* 'MLSD\r\n' 
*get* '150 Accepted data connection\n' 
*resp* '150 Accepted data connection' 
Traceback (most recent call last): 
    File "c:\my_script.py", line 384, in run_ftps 
    ftps.retrlines('MLSD') 
    File "c:\libs\Python36\lib\ftplib.py", line 485, in retrlines 
    conn.unwrap() 
    File "C:\libs\Python36\lib\ssl.py", line 1051, in unwrap 
    s = self._sslobj.unwrap() 
    File "C:\libs\Python36\lib\ssl.py", line 698, in unwrap 
    return self._sslobj.shutdown() 
OSError: [Errno 0] Error 

同樣的FTP命令(LIST)通過FileZilla的正常工作。

我可以用google搜索到的最接近的東西是:https://bugs.python.org/msg253161 - 我不確定它是否相關或相關。

短版本:「OSError:[Errno 0] Error」究竟意味着什麼,以及如何列出我的目錄內容?

編輯:這個問題似乎只發生在FTP_TLS。它通過普通的FTP連接正常工作,但我需要FTP_TLS。

回答

1
s = self._sslobj.unwrap() 
    File "E:\Software\_libs\Python36\lib\ssl.py", line 698, in unwrap 
    return self._sslobj.shutdown() 
OSError: [Errno 0] Error 

如果服務器只是關閉了TCP連接而沒有進行正確的TLS關閉,則會發生此錯誤。 OSError: [Errno 0]意味着底層TCP套接字實際上沒有錯誤,即服務器沒有正常關閉TCP套接字。只有在此之前,服務器纔會執行所需的TLS級別關閉。

這看起來像我在服務器實現中的錯誤,但也許這也是一個配置選項導致這一點。而且,python ftplib似乎在面對這種不正確的協議實現以及其他客戶端時表現得不夠寬容。但是您可以通過搜索"Server did not properly shut down TLS connection"與其他客戶找到類似的報告。

修正可能是將conn.unwrap()retrlinesretrbinary中的ftplib.py放入try ... except語句中,並忽略該錯誤。

相關問題