錯誤堆疊
org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication.
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:317)
常見原因
- FTP 服務器主動斷開(空閒超時、最大連接數限制)。
- 客戶端未正確處理被動/主動模式切換。
- 防火牆/NAT 截斷數據連接。
- 代碼中
finally 塊在連接已斷開時再次調用 disconnect() 導致二次異常掩蓋真因。
排查步驟
- 啟用 FTPClient 調試日誌:
ftpClient.addProtocolCommandListener(new PrintCommandListener(System.out));
- 檢查服務器日誌(vsftpd、FileZilla Server 等)。
- 嘗試設置被動模式:
ftpClient.enterLocalPassiveMode();
- 設置連接/數據超時:
ftpClient.setConnectTimeout(30000); ftpClient.setDefaultTimeout(30000);
代碼健壯性改進
public static boolean uploadFile(...) {
FTPClient ftp = new FTPClient();
try {
ftp.connect(url, port);
ftp.login(username, password);
ftp.enterLocalPassiveMode(); // 關鍵:穿透防火牆
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.changeWorkingDirectory(path);
try (InputStream input = new FileInputStream(localFile)) {
return ftp.storeFile(filename, input);
}
} catch (IOException e) {
log.error("FTP上傳失敗", e);
return false;
} finally {
if (ftp.isConnected()) {
try { ftp.logout(); ftp.disconnect(); }
catch (IOException ignored) {}
}
}
}
參考資源
參考:https://aspnetdb.iteye.com/blog/970408