1

単純な Java URL FTP 接続のローカル テスト セットアップに奇妙な問題があります。次のコード フラグメント (try/catch を削除):

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.

テスターが拡張パッシブモードに入ろうとしている理由と、 subFourを取得できなかった後にsubOneを追加した理由がまったくわかりません。

FileZilla サーバーをインストールし、匿名ユーザーと共有ドライブをセットアップしました。ブラウザーと FileZilla-Client を介して、FTP-Dir に到達できることを確認しました (もちろん同じログイン)。それだけです。すべてが同じマシンにインストールされ、実行されます。

これ以上わからない...

助けてくれてありがとう!

4

1 に答える 1

4

FTP に接続するこの方法は非常に限定されており、文書化されていません。まず EPSV についてお答えします。接続は内部実装によって確立されますが、これは私の JDK ではたまたまsun.net.www.protocol.ftp.FtpURLConnection.

EPSV最初にサーバーに接続して試行するとき(デフォルトはパッシブ モード) 、パッシブ モードを確立できない場合はPASV、アクティブ モードにフォールバックします。PORT実装の詳細については、こちらを参照してください。

あなたの質問の1つを説明する重要なコメントは次のとおりです。

 /**
  * 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
  */

2 番目の質問については、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       }

FTP 操作にはApache Commons Netライブラリを使用することをお勧めします。はるかに高度で使いやすいです。

歓声と楽しいデバッグをお望みなら!

于 2011-02-23T12:52:50.347 に答える