5

5 分ごとにリモートの場所にファイルを ftp するプロセスがあります。

何時間もスタックしているようで、ファイルを送信していません。

何が起こっているのかを確認するためにスレッド ダンプを取得しました。これが私のスレッドの状態です。

"SPPersister" prio=6 tid=0x03782400 nid=0x16c4 runnable [0x0468f000..0x0468fd14]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(Unknown Source)
        at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
        at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
        at sun.nio.cs.StreamDecoder.read(Unknown Source)
        - locked <0x239ebea0> (a java.io.InputStreamReader)
        at java.io.InputStreamReader.read(Unknown Source)
        at java.io.BufferedReader.fill(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        - locked <0x239ebea0> (a java.io.InputStreamReader)
        at java.io.BufferedReader.readLine(Unknown Source)
        at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:294)
        at org.apache.commons.net.ftp.FTP._connectAction_(FTP.java:364)
        at org.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java:540)
        at org.apache.commons.net.SocketClient.connect(SocketClient.java:178)
        at org.apache.commons.net.SocketClient.connect(SocketClient.java:268)
        ...

次のコードを使用して接続しています。

FTPClient client = new FTPClient();
client.setConnectTimeout(10000);
client.connect(host); // <-- stuck here
client.setDataTimeout(20000);
client.setSoTimeout(20000);
client.login(user, pass);
client.changeWorkingDirectory(dir);

接続試行が 10 秒以内にタイムアウトになったはずではありませんか?

4

2 に答える 2

4

はいといいえ。

接続が機能しなかったと仮定すると、接続は 10 秒以内にタイムアウトしますが、接続はおそらく機能し、現在はソケットからデータを読み取ろうとしています。おそらく最初の FTP ヘリシーケンスを邪魔にならないようにするためです。 [1]。実際、スタックトレースがスタックしているconnectAction ()の javadoc を見ると、まさにそれが行われています。

connect を呼び出す前にデータ タイムアウトを設定してみると、実際には期待どおりに失敗する可能性があります。これが機能しない場合は、おそらくapache-commons でバグを発生させる必要があります。このバグは、ほぼ確実に発生している問題です。

[1] RFC959 によると:

情報応答の重要なグループの 1 つは、接続グリーティングです。通常の状況では、接続が完了すると、サーバーは「入力待ち」という 220 応答を送信します。ユーザーは、コマンドを送信する前に、このグリーティング メッセージを待つ必要があります。サーバーが入力をすぐに受け入れることができない場合は、120 の「予想される遅延」応答をすぐに送信し、準備ができたら 220 応答を送信する必要があります。ユーザーは、遅延が発生した場合に電話を切らなくてもよいことがわかります。

これが、FTPClient クラスが外部側からの入力を待っている理由です。

于 2010-01-24T00:38:00.890 に答える
2

デバイスから FTP を試みる Java があり、commons-net/ftp を使用すると不可解にハングアップしました。あなたが見ているのと同じように。かなりの調査の後、どこかでそれが commons-net/ftp の欠陥であることを示すバグ レポートを見つけました。この欠陥は、応答を待っているときにネットワークがダウンしたときに発生します (不安定なワイヤレスがありました)。それが発生すると、それ自体が待機状態になり、返されませんでした。

残念ながら、私たちが見つけた解決策は、別のライブラリを使用することです。いろいろありますが、私たちが使ったのはこれです。 http://www.enterprisedt.com/products/edtftpj/overview.html

于 2010-01-24T00:53:02.457 に答える