FTP客户端收到网络错误javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接

时间:2018-02-27 15:24:38

标签: java ftp ftp-client ftps sslhandshakeexception

我正在尝试连接到需要“显式FTP over TLS”的FTP并上传文件。

我正在尝试从使用Java版本8和commons net FTP版本3.6

的本地计算机上执行此操作

以下是我使用的代码

          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);
            }

以下是我从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

以下是我尝试使用FileZilla进行连接时的日志。它连接正常,我可以传输文件。

但是当我尝试使用Java时,它没有转移

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

你能帮忙吗?

亲切的问候 乔恩

1 个答案:

答案 0 :(得分:0)

现代FTP服务器希望使用TLS会话恢复打开数据通道。 Java能够执行此操作,但仅用于连接到同一IP和端口。由于FTP会话的数据通道使用不同的端口,因此机制失败,因此您需要强制JVM执行此操作,并且使用反射包含非常繁重的java类实习生。

您正在使用Apache FTPSClient,因此您可能会检查它的更新版本是否已经为您执行了此操作,但如果仍未执行此操作,您可以自行执行,如Blog post中所述。在Wealthfront。

hack(我仍然无法以不同方式调用它)与客户端配合得很好但是如果你想在服务器端执行此操作还有一些重要的工作要做(即如果你想实现自己的FTP服务器) )。你的问题看起来不像,所以我将这一部分放在这个答案中。