问题
I am trying to connect to FTP that requires 'Explicit FTP over TLS' and upload a file.
I am trying to do it from my local machine which uses Java version 8 and commons net FTP version 3.6
Below is the code which I use
try {
FTPSClient ftpClient = new FTPSClient();
ftpClient.setDataTimeout(300);
ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
ftpClient.setAuthValue("TLS");
ftpClient.connect(server, port);
int reply = ftpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
ftpClient.execAUTH("TLS"); //SSL
// Login
if (ftpClient.login(user, pass)) {
// Set protection buffer size
ftpClient.execPBSZ(0);
// Set data channel protection to private
ftpClient.execPROT("P");
// Enter local passive mode
ftpClient.enterLocalPassiveMode();
ftpClient.changeWorkingDirectory("/");
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
File firstLocalFile = new File(outputFileNameCSV);
String firstRemoteFile = csvFileNameOut;
InputStream inputStream = new FileInputStream(firstLocalFile);
// Store file on host
boolean done = ftpClient.storeFile(firstRemoteFile, inputStream);
inputStream.close();
if (done)
{
System.out.println("The file is uploaded successfully.");
}
// Logout
ftpClient.logout();
} else {
System.out.println("FTP login failed");
}
// Disconnect
ftpClient.disconnect();
} else {
System.out.println("FTP connect to host failed");
}
} catch (IOException ioe) {
System.out.println("FTP client received network error "+ioe);
}
Below is the log I get from Java CommandListener
220-FileZilla Server 0.9.60 beta
220-written by Tim Kosse (tim.kosse@filezilla-project.org)
220 Please visit https://filezilla-project.org/
AUTH TLS
234 Using authentication type TLS
AUTH TLS
534 Authentication type already set to TLS
FTP login screen
USER test
331 Password required for test
PASS pass
230 Logged on
PBSZ 0
200 PBSZ=0
PROT P
200 Protection level set to P
CWD /
250 CWD successful. "/" is current directory.
TYPE I
200 Type set to I
PASV
227 Entering Passive Mode ()
STOR file.csv
150 Opening data channel for file upload to server of "/file.csv"
FTP client received network error javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
Below is the log when I try to connect using FileZilla. It is connecting fine and I can transfer the files.
But when I try using Java, it isn't transferring
Response: 220-FileZilla Server 0.9.60 beta
Response: 220-written by Tim Kosse (tim.kosse@filezilla-project.org)
Response: 220 Please visit https://filezilla-project.org/
Command: AUTH TLS
Response: 234 Using authentication type TLS
Status: Initializing TLS...
Status: Verifying certificate...
Command: USER test
Status: TLS/SSL connection established.
Response: 331 Password required for test
Command: PASS pass
Response: 230 Logged on
Command: PBSZ 0
Response: 200 PBSZ=0
Command: PROT P
Response: 200 Protection level set to P
Status: Connected
Status: Starting upload of file.csv
Command: CWD /
Response: 250 CWD successful. "/" is current directory.
Command: TYPE I
Response: 200 Type set to I
Command: PASV
Response: 227 Entering Passive Mode ()
Command: STOR file.csv
Response: 150 Opening data channel for file upload to server of "/file.csv"
Response: 226 Successfully transferred "/file.csv"
Status: File transfer successful, transferred 12,252 bytes in 1 second
Could you all please help?
Kind regards Jon
回答1:
Modern FTP servers expect the data channel to be opened by using TLS session resume. Java is capable of doing this but only for connections to the same IP and port. Because the data channel of an FTP session uses a different port the mechanism fails, so you need to force the JVM to do that and includes quite heavy fiddling with the interns of java classes using reflection.
You're using the Apache FTPSClient, so you might check if a more recent version of it already does that for you but if it's still not done, you might do it yourself as it is described in a Blog post on Wealthfront.
The hack (I still fail it to call it differently) works well with clients but there is some significant additional work to be done if you want to do this on a server side (i.e. if you want to implement you own FTP server). Your question doesn't look like it, so I spare this part in this answer.
来源:https://stackoverflow.com/questions/49012248/ftp-client-received-network-error-javax-net-ssl-sslhandshakeexception-remote-ho