客户端FTPClient连接时报错:
>2018-04-18 14:43:47,981 [main] ERROR com.test.ftpclient.FTPClientUtil - 无法连接至指定FTP服务器
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method) ~[na:1.8.0_77]
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79) ~[na:1.8.0_77]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_77]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_77]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_77]
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) ~[na:1.8.0_77]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_77]
at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_77]
at org.apache.commons.net.SocketClient.connect(SocketClient.java:182) ~[commons-net-3.3.jar:3.3]
at org.apache.commons.net.SocketClient.connect(SocketClient.java:203) ~[commons-net-3.3.jar:3.3]
at com.test.ftpclient.FTPClientUtil.<init>(FTPClientUtil.java:43) ~[ftp-test.jar:na]
at com.test.ftpclient.FtpMain.main(FtpMain.java:29) [ftp-test.jar:na]
服务端ftp日志显示:远程主机强迫关闭了一个现有的连接。
经过查找资料发现:ftp连接时主动模式与被动模式的区别
参考:ftp的主动模式active mode和被动模式 passive mode的配置和区别
结论:passive模式
服务端开启>1024端口等待客户端连接, 进行数据传输
active 模式:
服务端通过20端口(默认20,可以设置为其他端口)主动连接客户端>1024端口, 进行数据传输
回归前面的问题,客户端使用被动模式连接ftp,而服务端部署在阿里云上,端口只开了几个(21、80、3389等),所以此时客户端不能连接其他>1024的端口进行数据传输,所以在建立连接时报错。而此时将连接模式改为主动模式就可以成功上传文件(此时服务端20端口没有配置使用,猜测可能是服务端主动连接客户端,不存在aliyun入方向端口启用问题)
本次使用的Apache FtpServer,具体配置可修改配置ftpd-typical.xml
<server xmlns="http://mina.apache.org/ftpserver/spring/v1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://mina.apache.org/ftpserver/spring/v1 http://mina.apache.org/ftpserver/ftpserver-1.0.xsd
"
id="myServer" /*设置server的标志符,必须*/
max-logins="5" /*设置同时登陆的最大人数*/
anon-enabled="false" /*设置匿名登陆为不允许*/
max-anon-logins="0" /*设置匿名登陆用户为0个*/
max-login-failures="3" /*设置3次失败登陆后,关闭此链接*/
login-failure-delay="30000"/*设置失败登陆后下一次登陆所需的时间间隔,防止暴力破解,单位是微秒*/
>
<listeners>
<nio-listener name="default" port="2121"><!--设置默认的链接端口为2121,必须-->
<ssl>
<keystore file="./res/ftpserver.jks" password="password" /><!--设置密钥存储路径和密钥存储密码,必须-->
</ssl>
<data-connection idle-timeout="60"><!--设置多少时间后关闭一个闲置的链接,单位是秒-->
<active local-port="1886"/><!--设置主动链接配置,端口号“1886”默认端口20-->
<!--设置被动链接配置,端口设置为“1886”,也可以设置IP段“3001-3010”,扩展地址为“137.222.18.114”,当需要访问的服务器返回外网地址时使用-->
<passive ports="1886" address="0.0.0.0" external-address="137.222.18.114"/>
</data-connection>
</nio-listener>
</listeners>
<!--设置用户登陆信息,“./res/conf/users.properties”为文件路径,“encrypt-passwords=‘clear’”设置密码加密方式,默认是“MD5”,设置成“clear”表示不加密,直接输入-->
<file-user-manager file="./res/conf/users.properties" encrypt-passwords="clear"/>
</server>
设置被动模式下服务器随机开启端口的范围,然后将IP段加入aliyun入站规则中,就可以正常使用被动模式连接ftp了。
而服务端报错是在连接ftp结束时未正常0关闭连接,客户端数据传输结束,服务端强制释放此连接。