java FTP org.apache.commons.net.MalformedServerReplyException:截断的服务器回复:'220'

sd2*_*018 5 java ftp apache-commons-net

我正在使用 Java Apache Commons Net 库从 FTP 服务器下载文件。作为起点,我试图重用来自https://www.codejava.net/java-se/networking/ftp/java-ftp-file-upload-tutorial-and-example 的代码。通常,代码执行时没有问题/异常,但是对于一个特定的 FTP 服务器 ( ftp://ftp.nasdaqtrader.com/symboldirectory/nasdaqlisted.txt ) 我收到以下错误:

org.apache.commons.net.MalformedServerReplyException:截断的服务器回复:'220'

我的代码如下:

String server = "ftp.nasdaqtrader.com";
int port = 21;
String user = "anonymous";
String pass = "pw";

FTPClient ftpClient = new FTPClient();
try {

    ftpClient.connect(server, port);
    ftpClient.login(user, pass);
    ftpClient.enterLocalPassiveMode();
    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

    // APPROACH #1: using retrieveFile(String, OutputStream)
    String remoteFile1 = "/symboldirectory/nasdaqlisted.txt";
    File downloadFile1 = new File("C:\\filedirectory\\nasdaqlisted.txt");
    OutputStream outputStream1 =
        new BufferedOutputStream(new FileOutputStream(downloadFile1));
    boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
    outputStream1.close();

    if (success) {
        System.out.println("File #1 has been downloaded successfully.");
    }

    } catch (IOException ex) {
    System.out.println("Error: " + ex.getMessage());
    ex.printStackTrace();
} finally {
    try {
        if (ftpClient.isConnected()) {
            ftpClient.logout();
            ftpClient.disconnect();
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

从我的 Windows 终端连接会产生以下结果:

String server = "ftp.nasdaqtrader.com";
int port = 21;
String user = "anonymous";
String pass = "pw";

FTPClient ftpClient = new FTPClient();
try {

    ftpClient.connect(server, port);
    ftpClient.login(user, pass);
    ftpClient.enterLocalPassiveMode();
    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

    // APPROACH #1: using retrieveFile(String, OutputStream)
    String remoteFile1 = "/symboldirectory/nasdaqlisted.txt";
    File downloadFile1 = new File("C:\\filedirectory\\nasdaqlisted.txt");
    OutputStream outputStream1 =
        new BufferedOutputStream(new FileOutputStream(downloadFile1));
    boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
    outputStream1.close();

    if (success) {
        System.out.println("File #1 has been downloaded successfully.");
    }

    } catch (IOException ex) {
    System.out.println("Error: " + ex.getMessage());
    ex.printStackTrace();
} finally {
    try {
        if (ftpClient.isConnected()) {
            ftpClient.logout();
            ftpClient.disconnect();
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

对于类似的 FTP 服务器(NOAA 天气),代码通过 Windows 终端连接和下载无一例外地产生以下结果:

C:\Computer>ftp ftp.nasdaqtrader.com
Connected to ftp.nasdaqtrader.com.
220
200 OPTS UTF8 command successful - UTF8 encoding now ON.
User (ftp.nasdaqtrader.com:(none)): anonymous
331 Anonymous access allowed, send identity (e-mail name) as password.
Password:
230 User logged in.
ftp> quit
221 Goodbye.
Run Code Online (Sandbox Code Playgroud)

所以比较这两个回复,ftp.nasdaqtrader.com 似乎根本没有提供适当的(标准?)220 回复(即被截断)。所以:

  1. 我是否正确识别了问题,并且
  2. 处理这个问题的适当方法是什么?

谢谢!

Mar*_*ryl 9

Apache Commons Net 库认为220来自服务器的响应不符合 RFC 959(可能是正确的)。

如果要允许库与服务器通信,请调用FTP.setStrictReplyParsing

ftpClient.setStrictReplyParsing(false);
Run Code Online (Sandbox Code Playgroud)