org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication
Ftp问题
最近遇到了ftp读取中文乱码的问题,代码中使用的是FtpClient。google一下找到了解决方案。
FTP协议里面,规定文件名编码为iso-8859-1,FTP类中默认的编码也是这个。
public FTP() {
this.setDefaultPort(21);
this._replyLines = new ArrayList();
this._newReplyString = false;
this._replyString = null;
this._controlEncoding = "ISO-8859-1";
this._commandSupport_ = new ProtocolCommandSupport(this);
}
参考文章 https://www.cnblogs.com/chenfei0801/p/3427310.html 设置了编码格式
private FTPClient getClient(ConnectReq connectReq) {
String host = StringUtils.substringBefore(connectReq.getConnectUrl(), ":");
int port = Integer.parseInt(StringUtils.substringAfter(connectReq.getConnectUrl(), ":"));
log.info("Connect to Ftp [{}:{}] with user [{}] and passwd [{}].",
host, port, ftpReq.getUserName(), ftpReq.decodePassword());
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(host, port);
log.info("Connected.");
ftpClient.login(ftpReq.getUserName(), ftpReq.decodePassword());
// Use passive mode to pass firewalls.
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
"OPTS UTF8", "ON"))) {
LOCAL_CHARSET = UTF8_CHARSET;
}
ftpClient.setControlEncoding(LOCAL_CHARSET);
ftpClient.enterLocalPassiveMode();
log.info("Logged.");
return ftpClient;
} catch (IOException e) {
log.error("连接ftp服务-{} 出错,原因:{}", ftpReq.getHost(), e);
throw new InnerException(ErrorCode.DSOURCE_ERROR, e);
}
}
发现程序能够连接成功,但是在调用client.logout方法时出现了错误。
org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication.
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:313)
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:290)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:479)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:552)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:601)
at org.apache.commons.net.ftp.FTP.quit(FTP.java:809)
at org.apache.commons.net.ftp.FTPClient.logout(FTPClient.java:979)
...
java.lang.RuntimeException: org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication.
...
Caused by: org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication.
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:313)
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:290)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:479)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:552)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:601)
at org.apache.commons.net.ftp.FTP.quit(FTP.java:809)
at org.apache.commons.net.ftp.FTPClient.logout(FTPClient.java:979)
... 28 more
根据FTPClient官方文档的解释
/***
* Logout of the FTP server by sending the QUIT command.
* <p>
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean logout() throws IOException
{
return FTPReply.isPositiveCompletion(quit());
}
这个错误的出现的可能原因是ftp服务器过早关闭或者其他原因导致服务端返回了421。
继续追踪到后面的异常栈
Connection closed without indication.
这个问题可能是因为FTP服务器服务有故障,或是是网络问题。于是我立马用命令行尝试连接到Ftp上,果然是可以连的,证明ftp服务没问题。那么就是网络问题了。
检查了代码,在代码中使用的是被动模式。FTP服务器一般使用20和21两个端口与客户端进行通信,21端口用来传输FTP的控制命令,20端口用于传输文件数据。
如果是主动模式的话,FTP客户端向服务器的FTP控制端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路;当需要传送数据时,客户端在命令链路上用PORT的命令告诉服务器我开放了某端口,你过来连接我。于是服务器从20端口向客户端的该端口发送连接请求,建立一条数据链路来传送数据。在数据链路建立过程中是服务器主动请求,所以称为主动模式。
subgraph 客户端
client[客户端]
clientPort[打开端口]
client--2.打开-->clientPort
end
subgraph 服务端
server[服务端]
server-->port21
server-->port20
port21(21端口)
port20(20端口)
client--1.连接请求-->port21
client--3.PORT通知-->server
port20--4.建立连接-->clientPort
end
如果是被动模式的话,FTP客户端向服务器的FTP控制端口(默认21)发送连接请求,服务器接受连接,建立一条命令链路;当需要传送数据时,服务器在命令链路上用PASV命令告诉客户端,我打开了某端口,你过来连我。于是客户端向服务器的该端口发送连接请求,建立一条数据链路来传送数据。在数据链路建立的过程中是服务器被动等待客户机的请求,所以称被动模式。
subgraph 客户端
client[客户端]
clientConnect[建立数据链路]
client-->clientConnect
end
subgraph 服务端
server[服务端]
server-->port21
server--2.打开-->serverPort
port21(21端口)
serverPort(打开端口)
client--1.连接请求-->port21
server--3.PASV通知-->client
clientConnect--4.建立连接-->serverPort
end
上文说到代码中用的是被动模式,也就意味着服务端需要打开21端口和另一个端口供客户端连接。我使用的ftp是用docker装的,只透出了21端口,所以使用被动模式连接会出错。于是把这里改成主动模式,连接成功。
org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication的更多相关文章
- org.apache.commons.net.ftp
org.apache.commons.NET.ftp Class FTPClient类FTPClient java.lang.Object Java.lang.Object继承 org.apache. ...
- 【FTP】使用org.apache.commons.net.ftp.FTPClient 实现FTP的上传下载
在此之前,在项目中加上FTP的架包 第一步:配置FTP服务器的相关配置 FtpConfig.java 实体类(配置类) package com.sxd.ftp; public class FtpCo ...
- 【FTP】org.apache.commons.net.ftp.FTPClient实现复杂的上传下载,操作目录,处理编码
和上一份简单 上传下载一样 来,任何的方法不懂的,http://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net ...
- ftp org.apache.commons.net.ftp.FTPClient 判断文件是否存在
String path = "/SJPT/ONPUT/HMD_TEST/" ; FtpTool.getFTPClient().changeWorkingDirectory(path ...
- Java 利用Apache Commons Net 实现 FTP文件上传下载
package woxingwosu; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import ...
- Java使用Apache Commons Net实现FTP功能
maven依赖: <!-- https://mvnrepository.com/artifact/commons-net/commons-net --> <dependency> ...
- 使用apache commons net进行ftp传输
apache commons net的maven地址: http://mvnrepository.com/artifact/commons-net/commons-net/3.6 <!-- ht ...
- Apache Camel之FTP组件学习
写在最前面 哎,最近提了离职,手头的活也基本上清理的差不多了.想着这个把月可以舒服的晃悠晃悠的离开,但是运维的小伙伴总是不架势,走之前还是提了个新需求. 先说下需求吧,我们的系统概括的讲就是一个接口系 ...
- Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException:
七月 17, 2014 4:56:01 下午 org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service( ...
随机推荐
- Docker(一)Docker概述
Docker概述 概述 Docker是供开发人员和系统管理员 使用容器构建,运行和共享应用程序的平台.使用容器来部署应用程序称为容器化.容器不是新的,但用于轻松部署应用程序的容器却是新的. 容器化越来 ...
- rodert单排学习redis进阶【白银一】
redis之白银一 说些题外话,最近帝都疫情又严重,大家都身处时代洪流中,这不是个别人能左右的,希望你能保护好自己,天天开心. 前言 1.Redis 客户端 1.1.Redis Desktop Man ...
- Riccati方程迭代法求解
根据上述迭代法求解P,P为Riccati方程的解,然而用LQR需要计算K,再将K算出. (迭代过程中 ,我们可以将此算法和dlqr函数求解的参数进行对比,当误差小于我们设置的允许误差我们就可以把此算法 ...
- sql 语句和实例
修改字段格式的sql语句: alter table tablename alter column colname newDataType 比如:alter table mytable alter co ...
- 自描述C++部分面试题集
1.谈谈啥叫对象成员以及对象成员的构造函数调用调用方式. 在类中定义的数据成员一般都是基本的数据类型.但是类中的成员也可以是对象,叫做对象成员. C++中对对象的初始化时非常重要的操作,当创建一个对象 ...
- C语言学习笔记——特别篇(VScode安装使用)
B站有同步教学视频 参考博文: https://www.cnblogs.com/czlhxm/p/11794743.html 注意事项: 请在英文目录下运行!!! VScode下载链接: https: ...
- 资深前端工程师带你认识网页后缀html、htm、shtml、shtm有什么区别?
每一个网页或者说是web页都有其固定的后缀名,不同的后缀名对应着不同的文件格式和不同的规则.协议.用法,最常见的web页的后缀名是.html和.htm,但这只是web页最基本的两种文件格式,今天我们来 ...
- zsh切换bash提示chsh: no changes made问题
前提纪要:1.我们都知道mac有默认bash工具,在下载zsh后,把一切都配置好后,输入切换命令:chsh - s /bin/zsh ,总是提示 chsh: no changes made错误.那我我 ...
- 线下---复习day01
目录 1 个人介绍 2 关于编辑器 3 基础串讲 3.1 解释型和编译型 3.2 数据类型 3.2.1 一切皆对象 3.2.1 深浅copy 3.2.3 可变类型与不可变类型 3.3 字符编码 3.4 ...
- HTB::Postman
实验环境 渗透过程 0x01 信息搜集 masscan扫描 扫描结果目标服务开放了22(ssh),80(http),6379(redis),10000(webmin)端口 nmap扫描 nmap -s ...