使用Java Apache FTPClient进行FTP TLS时,获取;握手期间远程主机关闭连接”;
我在Windows1064X上运行了一个Java(1.8)程序,用于FTP TLS(org.apache.commons.net.FTP): 对于第一个FTP服务器(Microsoft FTP服务),工作正常!调试:使用Java Apache FTPClient进行FTP TLS时,获取;握手期间远程主机关闭连接”;,java,apache,ftp,ftps,apache-commons-net,Java,Apache,Ftp,Ftps,Apache Commons Net,我在Windows1064X上运行了一个Java(1.8)程序,用于FTP TLS(org.apache.commons.net.FTP): 对于第一个FTP服务器(Microsoft FTP服务),工作正常!调试: 运行: 220 Microsoft FTP服务 认证TLS 234验证命令正常。期待TLS谈判。 使用者******* 演示需要331密码。 通过******* 230用户已登录。 PBSZ 0 200 PBSZ命令成功。 保护蛋白 200保护命令成功。 第一类 200类型设置为I
运行:
220 Microsoft FTP服务
认证TLS
234验证命令正常。期待TLS谈判。
使用者*******
演示需要331密码。
通过*******
230用户已登录。
PBSZ 0
200 PBSZ命令成功。
保护蛋白
200保护命令成功。
第一类
200类型设置为I。
SSL:true
系统
215窗口
远程系统是Windows\u NT
协议[Ljava.lang.String;@3f2a3a5
作者:错
壮举
211支持的扩展功能:
朗恩*
UTF8
认证TLS;TLS-C;SSL;TLS-P;
PBSZ
蛋白C;P;
CCC
主办
大小
MDTM
静止流
211端
EPSV
229进入扩展被动模式(| | | 1025 |)
RETR/readme.txt
125数据连接已打开;传输开始。
226传输完成。
退出
再见。
生成成功(总时间:7秒)
对于第二个FTP服务器(FileZilla服务器0.9.59 beta版)出错,请调试:
运行:
220 FileZilla服务器0.9.59测试版
220蒂姆·科塞(Tim。kosse@filezilla-(project.org)
请访问https://filezilla-project.org/
认证TLS
234使用身份验证类型TLS
使用者*******
331 xxx需要密码
通过*******
230已登录
PBSZ 0
200 PBSZ=0
保护蛋白
200保护级别设置为P
第一类
200类型设置为I
SSL:true
系统
FileZilla模拟的215 UNIX
远程系统由FileZilla模拟UNIX
协议[Ljava.lang.String;@246ae04d
作者:错
壮举
211特点:
MDTM
静止流
大小
MLST类型*;尺寸*;修改*;
MLSD
身份验证SSL
认证TLS
保护
PBSZ
UTF8
CLNT
MFMT
EPSV
EPRT
211端
EPSV
229进入扩展被动模式(| | | | 14393 |)
RETR/readme.txt
150打开从“/readme.txt”服务器下载文件的数据通道
错误:握手期间远程主机关闭连接
javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接
退出
位于sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1002)
450数据连接的TLS会话未恢复或会话与控制连接不匹配
位于sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
位于sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
位于sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
在org.apache.commons.net.ftp.FTPSClient.\u openDataConnection\u(FTPSClient.java:646)
位于org.apache.commons.net.ftp.FTPClient.\u retrieveFile(FTPClient.java:1899)
位于org.apache.commons.net.ftp.FTPClient.retrieveFile(FTPClient.java:1885)
位于ftps.App_FTP.main(App_FTP.java:96)
原因:java.io.EOFException:SSL对等机错误关闭
位于sun.security.ssl.InputRecord.read(InputRecord.java:505)
位于sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
…还有7个
生成成功(总时间:5秒)
使用FileZilla客户端可以很好地工作(下载/上传文件),但是使用Java代码,我什么都做不了,只需要连接和登录。有什么建议吗?或者其他自动FTP TLS的解决方案吗
重要信息不是异常消息本身,而是日志中的此消息: 450数据连接的TLS会话未恢复或会话与控制连接不匹配 某些FTP服务器确实要求您重新使用TLS会话进行数据连接 ApacheCommonsNetLibrary本机还不支持这一点,但实现它并不困难 如何做到这一点,请参见我对的回答:
我使用Cyberduck库解决了这个问题。
首先,为什么会出现这种握手问题, 因为一些先进的FTP服务器只允许一个会话进行连接和数据传输 1) 控制会话->用于连接
2) 数据会话->数据存储/下载/等 那么如何解决这个问题呢 步骤1-: 首先,您需要从GitHub签出cyberduck回购协议。 从这里开始-: 步骤2-:您将在签出回购中看到FTP和核心模块 步骤3-:将此模块转换为maven并为其创建jar 步骤4-:将这个jar添加到您的项目中,但是这个jar还需要其他依赖项,所以也相应地将它们添加到项目构建路径中 步骤5-:代码片段
public class TestFTPS {
public static void main(String[] args) throws SocketException, IOException {
TrustManager[] trustManagers = new TrustManager[] { new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
} };
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, new SecureRandom());
} catch (Exception e) {
e.printStackTrace();
}
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
Protocol protocol = new FTPTLSProtocol();
FTPClient client = new FTPClient(protocol, sslSocketFactory, sslContext);
client.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
client.connect(ftphostname, port);
client.execAUTH("TLS"); //SSL
System.out.println(client.getReplyCode());
if (client.login(username, password)) {
client.execPBSZ(0);
client.execPROT("P");
String date = "Testing Data Send to provide FTP location";
client.setFileType(FTP.BINARY_FILE_TYPE);
client.enterLocalPassiveMode();
InputStream is = new ByteArrayInputStream(date.getBytes());
client.storeFile("test.txt", is);
System.out.print(client.getReplyCode());
}
}
}
步骤6-:运行此代码后,您的文件将成功传输到ftp位置
注意-:请在项目中添加所需的jar
希望这能对您有所帮助。您能解释一下如何执行步骤3吗?
public class TestFTPS {
public static void main(String[] args) throws SocketException, IOException {
TrustManager[] trustManagers = new TrustManager[] { new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
} };
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, new SecureRandom());
} catch (Exception e) {
e.printStackTrace();
}
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
Protocol protocol = new FTPTLSProtocol();
FTPClient client = new FTPClient(protocol, sslSocketFactory, sslContext);
client.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
client.connect(ftphostname, port);
client.execAUTH("TLS"); //SSL
System.out.println(client.getReplyCode());
if (client.login(username, password)) {
client.execPBSZ(0);
client.execPROT("P");
String date = "Testing Data Send to provide FTP location";
client.setFileType(FTP.BINARY_FILE_TYPE);
client.enterLocalPassiveMode();
InputStream is = new ByteArrayInputStream(date.getBytes());
client.storeFile("test.txt", is);
System.out.print(client.getReplyCode());
}
}
}