1

我的简单 Java URL FTP 连接的本地测试设置有一个奇怪的问题。以下代码片段(删除了尝试/捕获):

URL url = new URL("ftp://127.0.0.1/subOne/subTwo/subThree/subFour");
URLConnection conn = url.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);

InputStream is = conn.getInputStream(); /// And here flies the IOException!

...实际的 IOException-Cause 是“subOne/subTwo/subThree/subFour”,但有趣的事情发生在服务器端:

(000012)23.02.2011 13:01:05 - (not logged in) (127.0.0.1)> Connected, sending welcome message...
(000012)23.02.2011 13:01:05 - (not logged in) (127.0.0.1)> 220 Blabla
(000012)23.02.2011 13:01:05 - (not logged in) (127.0.0.1)> USER anonymous
(000012)23.02.2011 13:01:05 - (not logged in) (127.0.0.1)> 331 Password required for anonymous
(000012)23.02.2011 13:01:05 - (not logged in) (127.0.0.1)> PASS *************
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> 230 Logged on
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> TYPE I
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> 200 Type set to I
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> CWD das
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> 250 CWD successful. "/subOne" is current directory.
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> CWD 2011
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> 250 CWD successful. "/subOne/subTwo" is current directory.
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> CWD 02
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> 250 CWD successful. "/subOne/subTwo/subThree" is current directory.
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> EPSV ALL
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> 229 Entering Extended Passive Mode (|||3881|)
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> EPSV
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> 229 Entering Extended Passive Mode (|||3882|)
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> RETR subFour
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> 550 File not found
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> CWD subOne
(000012)23.02.2011 13:01:05 - anonymous (127.0.0.1)> 550 CWD failed. "/subOne/subTwo/subThree/subOne": directory not found.
(000012)23.02.2011 13:03:06 - anonymous (127.0.0.1)> 421 Connection timed out.
(000012)23.02.2011 13:03:06 - anonymous (127.0.0.1)> disconnected.

我根本不明白,为什么 Tester 试图进入扩展的被动模式以及为什么它在无法检索 subFour 之后添加了subOne

我刚刚安装了 FileZilla 服务器并设置了匿名用户和共享驱动器。我通过浏览器和 FileZilla-Client 检查了 FTP-Dir 是可访问的(当然是相同的登录),就是这样。一切都安装并运行在同一台机器上!

以后不知道了...

谢谢你的帮助!

4

1 回答 1

4

这种连接到 FTP 的方式非常有限,而且文档也很模糊。我可以先给你一个EPSV的答案。连接是由内部实现建立的,在我的 JDK 中恰好是sun.net.www.protocol.ftp.FtpURLConnection.

当首先连接到服务器EPSV并将PASV尝试(默认为被动模式)时,它将回退到主动模式PORT- 如果无法建立被动模式。您可以在此处查看实现细节。

解释您的一个问题的基本评论是:

 /**
  * Here is the idea:
  *
  * - First we want to try the new (and IPv6 compatible) EPSV command
  *   But since we want to be nice with NAT software, we'll issue the
  *   EPSV ALL cmd first.
  *   EPSV is documented in RFC2428
  * - If EPSV fails, then we fall back to the older, yet OK PASV command
  * - If PASV fails as well, then we throw an exception and the calling method
  *   will have to try the EPRT or PORT command
  */

至于你的第二个问题...... subFour的不成功检索......好吧,乍一看,它似乎表现得那样,因为它是错误的。但是我现在无法真正安装正确的环境来验证这一点。此外,您还有例外。我猜这个问题是在第 455 行尝试再次导航到完整路径时引发的。FTP 连接的完整来源在这里

373       public InputStream getInputStream() throws IOException {
  ...
  390           try {
  391               decodePath(url.getPath());
  392               if (filename == null || type == DIR) {
  ...
  399               } else {
  400                   if (type == ASCII)
  401                       ftp.ascii();
  402                   else
  403                       ftp.binary();
  404                   cd(pathname);
  405                   is = new FtpInputStream(ftp, ftp.get(filename));
  406               }
  407   
  408
  ...
  453           } catch (FileNotFoundException e) {
  454               try {
  455                   cd(fullpath);
  456                   /* if that worked, then make a directory listing
  457                      and build an html stream with all the files in
  458                      the directory */
  459                   ftp.ascii();
  460   
  461                   is = new FtpInputStream(ftp, ftp.list());
  462                   msgh.add("content-type", "text/plain");
  463               } catch (IOException ex) {
  464                   throw new FileNotFoundException(fullpath);
  465               }
  466           }
  ...
  469       }

我建议您使用Apache Commons Net库进行 FTP 操作。它使用起来更加先进和简单。

如果你愿意的话,干杯和愉快的调试!

于 2011-02-23T12:52:50.347 回答