首先是一个前置条件:
一般我们搭建FTP服务后,在开发或者测试环境会使用真实IP至今访问,但是在生产环境,为了保证环境的可用性,比如机器宕机或者其它原因,我们不会直接通过真实IP连接FTP,而是在前面使用VIP(virtual IP),这样如果FTP服务出现问题,客户端不用做修改。
当我们使用Apache的commons-net包操作FTP时,一般我们初始化客户端为:FTPClient ftpClient = new FTPClient();
分析源码发现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public FTPClient() { __initDefaults(); __dataTimeout = -1; //****这一行要求进行远程验证**** __remoteVerificationEnabled = true; __parserFactory = new DefaultFTPFileEntryParserFactory(); __configuration = null; __listHiddenFiles = false; __useEPSVwithIPv4 = false; __random = new Random(); __passiveLocalHost = null; } |
当我们上传下载文件操作时,会调用 打开数据链接 方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | protected Socket _openDataConnection_(String command, String arg) throws IOException { //....省略建立socket逻辑.... if (__remoteVerificationEnabled && !verifyRemote(socket)) { socket.close(); throw new IOException( "Host attempting data connection " + socket.getInetAddress().getHostAddress() + " is not same as server " + getRemoteAddress().getHostAddress()); } return socket; } |
当执行if (__remoteVerificationEnabled && !verifyRemote(socket))
时,因为初始化时设置__remoteVerificationEnabled = true
所有会去校验socket地址,但是我们使用的是VIP,这样就会出现地址不一致,链接关闭,要上传下载文件的操作也GameOver
解决很简单,只要设置__remoteVerificationEnabled = false
不进行校验即可
在FTPClient初始化后,调用 ftpClient.setRemoteVerificationEnabled(false)
即可
- 本文作者:fred.zhu
- 本文链接:https://www.zfred.top/java/libs/apache/common_net_ftp_vip.html
- 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN 许可协议。转载请注明出处!