ftp上传错误org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication

报错信息

ftp上传文件报org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication错误
在这里插入图片描述
项目中由于ftp做了迁移,代码使用的ftpclient登录成功,但是上传文件就报这个错误。

代码

public boolean uploadFile(String ip, int port, String username,  
			   String password, String serverpath, String file) {
		 // 初始表示上传失败  
		 boolean success = false;  
		 // 创建FTPClient对象  
		 FTPClient ftp = new FTPClient();  
		 ftp.setControlEncoding("UTF-8");
		 ftp.setConnectTimeout(20000);
		 ftp.setDataTimeout(600000);
		 ftp.enterLocalPassiveMode();
		 ftp.setActivePortRange(4000, 4100);

		 try {
			 int reply=0;  
			 // 连接FTP服务器  
			 // 如果采用默认端口,可以使用ftp.connect(ip)的方式直接连接FTP服务器  
			 ftp.connect(ip, port);  
			 //ftp.connect("192.168.20.221", 21);  
			 // 登录ftp

             ftp.login(username, password);
			 // 看返回的值是不是reply>=200&&reply<300 如果是,表示登陆成功

             reply = ftp.getReplyCode();
             logger.info("连接ftp服务器响应码,reply={}",reply);

             // 以2开头的返回值就会为真
			 if (!FTPReply.isPositiveCompletion(reply)) {
                 ftp.disconnect();
				 return success;  
			 }
			   
			 ftp.setActivePortRange(40000, 41000);

			 logger.info("ftp连接成功。。。file = {}, serverpath = {}", file, serverpath);
			 checkPathExist(ftp,iso8859ToGbk(serverpath));
     
			 //输入流  
			 InputStream input=null;
			 try {  
				 file=gbkToIso8859(file);  
				 input = new FileInputStream(iso8859ToGbk(file));  
			 } catch (Exception e) {
				 LoggerFactory.getLogger(this.getClass()).error("读取上传文件出错",e);
			 }  
			 // 将上传文件存储到指定目录  
			 file=iso8859ToGbk(file);
			 
			 String fileName =  getFilename(file);//8859
			 
			 int index = fileName.lastIndexOf(".");
			 String tmpFileName = fileName.substring(0,index)+".tmp";
			 
			 ftp.deleteFile(iso8859ToGbk(fileName));
			 
			 ftp.setFileType(FTPClient.BINARY_FILE_TYPE);

			 String ftpPath = iso8859ToGbk(serverpath)+"/"+iso8859ToGbk(tmpFileName);

			 logger.info("上传前ftp路径,ftpPath = {}",ftpPath);

			 boolean flag = ftp.storeFile(ftpPath, input);

             logger.info("上传文件后,上传结果flag = {}", flag);

             // 关闭输入流
			 input.close();
			 
			 if(flag){
				 ftp.rename(iso8859ToGbk(serverpath)+"/"+iso8859ToGbk(tmpFileName),
						 iso8859ToGbk(serverpath)+"/"+iso8859ToGbk(fileName));
				 success = true;
			 }

			 // 退出ftp  
			 ftp.logout();  
		 } catch (IOException e) {  
			 success = false;
			 LoggerFactory.getLogger(this.getClass()).error("上传数据到ftp出错",e);
		 } finally {  
			 if (ftp.isConnected()) {  
				 try {  
					 ftp.disconnect();  
				 } catch (IOException ioe) {  
					 LoggerFactory.getLogger(this.getClass()).info(ioe.toString());
				 }  
			 }  
		 }  
		 return success;  
	 } 

ftp主被动模式介绍

主动模式:FTP客户端向服务器的FTP控制端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路;当需要传送数据时,客户端在命令链路上用PORT的命令告诉服务器我开放了某端口,你过来连接我。于是服务器从20端口向客户端的该端口发送连接请求,建立一条数据链路来传送数据。在数据链路建立过程中是服务器主动请求,所以称为主动模式。

被动模式:FTP客户端向服务器的FTP控制端口(默认21)发送连接请求,服务器接受连接,建立一条命令链路;当需要传送数据时,服务器在命令链路上用PASV命令告诉客户端,我打开了某端口,你过来连我。于是客户端向服务器的该端口发送连接请求,建立一条数据链路来传送数据。在数据链路建立的过程中是服务器被动等待客户机的请求,所以称被动模式。

原因分析

看我们上面的代码,就知道,在ftp登录成功后,执行了ftp.setActivePortRange(40000, 41000);,这个表示使用主动模式传输数据,主动模式需要ftp服务器连我们的端口,结果,由于网络问题,ftp服务器无法连接客户端的端口,所以就报了这个错误。

解决方案

对于这个问题,应该有两种解决方案:一、开通网络,是ftp服务器能够连接客户端40000~41000的端口;二、就是改成被动模式。
在这里我就采取了第二种方法:在ftp客户端登录成功后(在登录之前执行是无效的),执行ftp.enterLocalPassiveMode();就可以了,最终代码如下:

public boolean uploadFile(String ip, int port, String username,  
			   String password, String serverpath, String file) {
		 // 初始表示上传失败  
		 boolean success = false;  
		 // 创建FTPClient对象  
		 FTPClient ftp = new FTPClient();  
		 ftp.setControlEncoding("UTF-8");
		 ftp.setConnectTimeout(20000);
		 ftp.setDataTimeout(600000);
		 ftp.enterLocalPassiveMode();
		 ftp.setActivePortRange(4000, 4100);

		 try {
			 int reply=0;  
			 // 连接FTP服务器  
			 // 如果采用默认端口,可以使用ftp.connect(ip)的方式直接连接FTP服务器  
			 ftp.connect(ip, port);  
			 //ftp.connect("192.168.20.221", 21);  
			 // 登录ftp

             ftp.login(username, password);
			 // 看返回的值是不是reply>=200&&reply<300 如果是,表示登陆成功

             reply = ftp.getReplyCode();
             logger.info("连接ftp服务器响应码,reply={}",reply);

             // 以2开头的返回值就会为真
			 if (!FTPReply.isPositiveCompletion(reply)) {
                 ftp.disconnect();
				 return success;  
			 }
			   
			 ftp.enterLocalPassiveMode();// 这是改为被动模式

			 logger.info("ftp连接成功。。。file = {}, serverpath = {}", file, serverpath);
			 checkPathExist(ftp,iso8859ToGbk(serverpath));
     
			 //输入流  
			 InputStream input=null;
			 try {  
				 file=gbkToIso8859(file);  
				 input = new FileInputStream(iso8859ToGbk(file));  
			 } catch (Exception e) {
				 LoggerFactory.getLogger(this.getClass()).error("读取上传文件出错",e);
			 }  
			 // 将上传文件存储到指定目录  
			 file=iso8859ToGbk(file);
			 
			 String fileName =  getFilename(file);//8859
			 
			 int index = fileName.lastIndexOf(".");
			 String tmpFileName = fileName.substring(0,index)+".tmp";
			 
			 ftp.deleteFile(iso8859ToGbk(fileName));
			 
			 ftp.setFileType(FTPClient.BINARY_FILE_TYPE);

			 String ftpPath = iso8859ToGbk(serverpath)+"/"+iso8859ToGbk(tmpFileName);

			 logger.info("上传前ftp路径,ftpPath = {}",ftpPath);

			 boolean flag = ftp.storeFile(ftpPath, input);

             logger.info("上传文件后,上传结果flag = {}", flag);

             // 关闭输入流
			 input.close();
			 
			 if(flag){
				 ftp.rename(iso8859ToGbk(serverpath)+"/"+iso8859ToGbk(tmpFileName),
						 iso8859ToGbk(serverpath)+"/"+iso8859ToGbk(fileName));
				 success = true;
			 }

			 // 退出ftp  
			 ftp.logout();  
		 } catch (IOException e) {  
			 success = false;
			 LoggerFactory.getLogger(this.getClass()).error("上传数据到ftp出错",e);
		 } finally {  
			 if (ftp.isConnected()) {  
				 try {  
					 ftp.disconnect();  
				 } catch (IOException ioe) {  
					 LoggerFactory.getLogger(this.getClass()).info(ioe.toString());
				 }  
			 }  
		 }  
		 return success;  
	 } 

期望对大家有所帮助。

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误通常出现在你的 Java 项目中使用了 Apache Commons Net 库,但是该库没有被正确地添加到类路径中。你需要在项目中添加正确版本的 Apache Commons Net 库。 如果你使用 Maven 进行依赖管理,可以在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.7.2</version> </dependency> ``` 如果你手动管理依赖,可以下载适当版本的 Apache Commons Net 库,并将其添加到类路径中。 如果你已经添加了正确的库但仍然遇到此错误,请确保你的构建工具(例如 Maven 或 Gradle)正在正确地构建项目,并且库已被正确地包含在项目中。 ### 回答2: java.lang.NoClassDefFoundError: org.apache.commons.net.ftp.FTPClient是一个Java异常,表示找不到org.apache.commons.net.ftp.FTPClient类。 这个错误通常发生在类加载器不能在运行时找到所需的类文件时。在这种情况下,出现了一个或多个可能的原因: 1. 缺少依赖项:发生这个错误最常见的原因是缺少所需的依赖项。在这种情况下,你需要确保你的项目中包含了Apache Commons Net库的JAR文件。你可以通过将该库添加到项目的构建路径中来解决此问题。 2. 类路径问题:如果你已经添加了正确的依赖项但仍然发生此错误,可能是由于类路径设置不正确造成的。请确保你的类路径包括了包含所需类文件的路径。 3. 版本不匹配:有时候,当你使用的类库的版本与你项目中的其他依赖项不兼容时,会发生NoClassDefFoundError错误。在这种情况下,你需要确保你所使用的类库的版本与其他依赖项相匹配。 解决这个错误的步骤如下: 1. 检查你的项目中是否包含了正确的依赖项。 2. 确保你的类路径设置正确并且包含了所有必要的类文件。 3. 检查你项目中所有依赖项的版本是否匹配。 如果你按照上述步骤操作仍然无法解决问题,你可以尝试在互联网上搜索更多关于该错误的解决方案或者咨询开发社区的帮助。 ### 回答3: java.lang.NoClassDefFoundError: org.apache.commons.net.ftp.FTPClient是Java中的一个异常错误,表示找不到org.apache.commons.net.ftp.FTPClient类。 在Java开发中,这个错误通常是由于缺少相关的jar包或类路径配置错误引起的。解决这个错误的方法包括: 1. 确保你的项目中包含了org.apache.commons.net.ftp.FTPClient类所在的jar包。这个类通常位于Apache Commons Net库中,你需要将这个jar包添加到你的项目的构建路径中。 2. 检查你的类路径配置是否正确。如果你使用的是Eclipse等IDE,你可以确认你的项目构建路径中包含了Apache Commons Net库。 3. 如果你已经正确导入了jar包并配置了类路径,但仍然出现这个错误,你可以检查一下jar包是否被正确部署到了服务器或者运行环境中。 总而言之,解决java.lang.NoClassDefFoundError: org.apache.commons.net.ftp.FTPClient错误的方法是确保项目中包含了所需的jar包,并配置了正确的类路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值