我的本地测试 - 设置一个简单的Java URL FTP连接有一个奇怪的问题。 下面的代码片段(删除try / catches):
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 - 原因是“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.
我根本不明白为什么测试人员试图进入扩展被动模式以及为什么在无法检索之后添加 subOne 子四
我刚安装了FileZilla Server并设置了匿名用户和共享驱动器。我通过浏览器和FileZilla-Client检查了FTP-Dir是否可以访问(当然是相同的登录),就是这样。 一切都安装在同一台机器上运行!
不知道任何进一步......
感谢您的帮助!
答案 0 :(得分:4)
这种连接到FTP的方式非常有限并且模糊不清。我可以先给你一个EPSV的答案。连接是通过内部实现建立的,在我的JDK中恰好是sun.net.www.protocol.ftp.FtpURLConnection
。
当首先连接到服务器EPSV
并尝试PASV
时(默认为被动模式),它将回归到主动模式 - PORT
- 如果被动模式无法建立。您可以查看实施详细信息here。
解释您的一个问题的基本评论是:
/**
* 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连接的完整来源是here。
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操作。它使用起来更先进,更直接。
如果你愿意,欢呼和快乐的调试!