【问题标题】:FTP client received network error javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshakeFTP 客户端收到网络错误 javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接
【发布时间】:2018-08-07 07:27:53
【问题描述】:

我正在尝试连接到需要“基于 TLS 的显式 FTP”的 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

大家可以帮忙吗?

亲切的问候 乔恩

【问题讨论】:

  • 将上传过程放入自己的try/catch-block中,以便在注销等情况下继续会话。也许PrintCommandListener可以提供更多来自服务器的信息。我假设 SSL 会话恢复没有发生,所以应该有一些来自服务器的消息。当然,是否返回实际消息取决于服务器,但值得一试。
  • @Lothar 是的,看起来简历没有发生。我收到 450 TLS 数据连接会话未恢复或会话与控制连接不匹配。请问您知道如何解决这个问题吗?
  • 我会发布一个关于这个的答案

标签: java ftp ftp-client ftps sslhandshakeexception


【解决方案1】:

现代 FTP 服务器期望通过使用 TLS 会话恢复来打开数据通道。 Java 能够做到这一点,但仅适用于到相同 IP 和端口的连接。由于 FTP 会话的数据通道使用不同的端口,机制会失败,因此您需要强制 JVM 执行此操作,并且包括使用反射对 java 类的实习生进行大量摆弄。

您正在使用 Apache FTPSClient,因此您可以检查它的更新版本是否已经为您执行此操作,但如果仍未完成,您可以按照 Wealthfront 上的 Blog post 中的说明自行执行.

黑客(我仍然无法以不同的方式称呼它)在客户端上运行良好,但如果您想在服务器端执行此操作(即,如果您想实现自己的 FTP 服务器,则需要完成一些重要的额外工作) )。你的问题看起来不像,所以我在这个答案中省略了这部分。

【讨论】:

    猜你喜欢
    • 2012-08-12
    • 2018-07-29
    • 2017-06-25
    • 2014-12-23
    • 2016-05-27
    • 1970-01-01
    • 2016-03-18
    • 2017-03-03
    相关资源
    最近更新 更多