FTP上傳文件,報錯java.net.SocketException: Software caused connection abort: recv failed


FTP上傳功能,使用之前寫的代碼,一直上傳都沒有問題,今天突然報這個錯誤:

java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.read(BufferedReader.java:175)
at org.apache.commons.net.io.CRLFLineReader.readLine(CRLFLineReader.java:58)
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:314)
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:294)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:483)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:608)
at org.apache.commons.net.ftp.FTP.port(FTP.java:932)
at org.apache.commons.net.ftp.FTPClient._openDataConnection_(FTPClient.java:812)
at org.apache.commons.net.ftp.FTPClient._storeFile(FTPClient.java:633)
at org.apache.commons.net.ftp.FTPClient.__storeFile(FTPClient.java:624)
at org.apache.commons.net.ftp.FTPClient.storeFile(FTPClient.java:1976)
at cn.com.fp.util.ftp.FavFTPUtil.uploadFile(FavFTPUtil.java:62)
at cn.com.fp.util.ftp.FavFTPUtil.uploadFileFromProduction(FavFTPUtil.java:139)
at cn.com.fp.util.ftp.FavFTPUtil.main(FavFTPUtil.java:363)

 

因為之前遇到過,都是流的非正常關閉導致的,我關閉所有進程,MyEclipse重啟,項目重啟,仍然報這個錯誤,又重啟電腦,仍然存在;意識到必須找到原因所在,否則都是做一些無用功。

上網找了一些博客,才發現問題根源,客戶提供的服務器是Linux,而我的代碼是在Windows 10下運行的,因為ftp server可能每次開啟不同的端口來傳輸數據,但是在linux上或者其他服務器上面,由於安全限制,可能某些端口沒有開啟,所以就出現阻塞,也就是感到代碼運行特別慢、受阻的原因,如何解決呢?如下:

添加FTPClient.enterLocalPassiveMode();這行代碼,即每次數據連接之前,ftp client告訴ftp server開通一個端口來傳輸數據。

代碼Demo如下:

      /**
	 * 上傳文件(可供Action/Controller層使用)
	 * 
	 * @param hostname
	 *            FTP服務器地址
	 * @param port
	 *            FTP服務器端口號
	 * @param username
	 *            FTP登錄帳號
	 * @param password
	 *            FTP登錄密碼
	 * @param pathname
	 *            FTP服務器保存目錄
	 * @param fileName
	 *            上傳到FTP服務器后的文件名稱
	 * @param inputStream
	 *            輸入文件流
	 * @return
	 */
	public static boolean uploadFile(String hostname, int port,
			String username, String password, String pathname, String fileName,
			InputStream inputStream) {
		boolean flag = false;
		FTPClient ftpClient = new FTPClient();
		try {
			// 連接FTP服務器
			ftpClient.connect(hostname, port);
			// 登錄FTP服務器
			ftpClient.login(username, password);
			ftpClient.setControlEncoding("UTF-8"); // 中文支持
			ftpClient.setConnectTimeout(5000); 	 // 超時設置
			// 是否成功登錄FTP服務器
			int replyCode = ftpClient.getReplyCode();
			if (!FTPReply.isPositiveCompletion(replyCode)) {
				ftpClient.disconnect();
				return flag;
			}
			ftpClient.enterLocalPassiveMode();
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftpClient.changeWorkingDirectory(pathname);
			ftpClient.storeFile(fileName, inputStream);
			inputStream.close();
			ftpClient.logout();
			flag = true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return flag;
	}

 特此記錄,希望能幫助需要的人!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM