在做一件什么事情
当时做在做一个文件上传下载的功能,其中涉及到的是存储FTP服务器。这个系统是某司的内部系统,我们在七楼开发调试,完是到三楼部署。
遇到了什么问题
当时就遇到了一个很奇怪的问题。问题现象是获取列表的时候,返回数据为空,有时候还会提示链接断开。这个问题坑的我和领导楼上楼下跑了七八趟。
ftpUtilsInst.list(path);
问题分析
连接断开容易解决,断开了为重新连接就可以了。
一开始猜想是应该有个参数可以配置对应的连接时间,结果发现还真有。
/**
* Sets the connection timeout in milliseconds, which will be passed to the {@link Socket} object's
* connect() method.
* @param connectTimeout The connection timeout to use (in ms)
* @since 2.0
*/
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
但是问题还是没有解决,就算是这个时间你设置的很长,最终还是有断开连接的一天。
那我们就自己封装一层,每次使用的使用重新建立连接⬇︎⬇︎⬇︎⬇
public FTPFile[] list(String path) throws IOException {
FTPFile[] listFiles = null;
try {
listFiles = ftpUtilsInst.list(path);
} catch (FTPConnectionClosedException e) {
logger.error("ftp closed: {}", e);
if (ftpUtilsInst.connect()) {
listFiles = ftpUtilsInst.list(path);
} else {
throw e;
}
}
return listFiles;
}
这样就把连接断开的问题解决了
目录下面有数据,但返回列表为空
原因是因为FTP有两种工作模式。一种是主动模式,一种是被动模式。
-
主动模式传输过程
1.当客户端需要从 FTP 服务器下载文件或者上传文件时,首先会与 FTP 服务器建立一个控制连接。这个控制连接是由客户端发起的,通过 TCP 协议连接到 FTP 服务器的 21 端口。
2.客户端在控制连接上发送 PORT 命令给服务器。这个命令包含了客户端用于接收数据的 IP 地址和端口号。例如,客户端告诉服务器自己的 IP 地址是 192.168.1.10,并且数据接收端口是 1025(这个端口号通常是大于 1024 的临时端口)
3.服务器收到 PORT 命令后,会使用 20 端口主动向客户端指定的 IP 地址和端口号发起一个数据连接,用于传输文件数据。主动的优点是:
从服务器的角度来看,主动模式相对简单,因为服务器只需要按照标准流程,使用 20 端口主动连接客户端即可。
主动的缺点是:
在一些网络环境下可能会出现问题。例如,如果客户端位于防火墙或者 NAT(网络地址转换)设备后面,防火墙可能会阻止来自外部服务器的主动连接请求。因为防火墙通常会默认阻止外部主机主动向内部网络的主机发起连接,除非进行特殊的配置。 -
被动模式传输过程
1.客户端先与 FTP 服务器建立控制连接,通过 TCP 协议连接到服务器的 21 端口。
2.客户端发送 PASV 命令给服务器,请求服务器进入被动模式。
3.服务器收到 PASV 命令后,会分配一个临时的端口号(大于 1024),并将自己的 IP 地址和这个临时端口号通过控制连接返回给客户端。例如,服务器返回的信息可能是(192.168.2.20,1026),表示服务器的数据连接端口是 1026。
4.客户端收到服务器返回的 IP 地址和端口号后,主动向服务器的这个端口发起数据连接,从而建立用于文件传输的数据通道。被动优点:
对于位于防火墙或 NAT 设备后面的客户端更加友好。因为这种模式下是客户端主动发起连接,符合大多数防火墙的安全策略,即允许内部网络的主机主动向外发起连接。
被动缺点:
服务器需要额外的配置来支持被动模式。并且在一些情况下,服务器可能会受到恶意攻击,例如攻击者可能会尝试扫描服务器返回的临时端口号,以寻找安全漏洞。
最终的方案
在每次客户端连接的时候,就要告诉服务器,我们是被动方式连接,添加这行代码设置:
//设置为被动模式
ftpClient.enterLocalPassiveMode();
注意:ftp server可能每次开启不同的端口来传输数据,但是在linux 上,由于安全限制,可能某些端口没有开启,所以就出现阻塞。
标签:端口,获取,listFiles,端口号,服务器,主动,连接,FTPClient,客户端 From: https://www.cnblogs.com/euler-blog/p/18618002