обыкновенный net ftp тупик? - PullRequest
4 голосов
/ 24 января 2010

У меня есть процесс, который должен передавать файл в удаленный каталог каждые 5 минут.

Кажется, он застрял на несколько часов и не отправлял файлы.

Я взял дамп потока, чтобы посмотреть, что происходит, и это состояние моего потока:

"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 секунд?

Ответы [ 2 ]

3 голосов
/ 24 января 2010

Да, и нет.

Время соединения истекло в течение десяти секунд, если предположить, что соединение не сработало, однако соединение, вероятно, сработало, и теперь оно пытается прочитать данные из сокета, скорее всего, получит исходную последовательность битов FTP пути [1]. В самом деле, глядя на javadoc для connectAction () , где находится ваша трассировка стека, это именно то, что она делает.

Вы можете попробовать установить тайм-аут данных перед вызовом connect, таким образом, он может фактически потерпеть неудачу так, как вы ожидаете. Если это не сработает, вам, скорее всего, нужно поднять ошибку с помощью apache-commons . Эта ошибка почти наверняка является проблемой, которую вы видите.

[1] Согласно RFC959:

Одной из важных групп информационных ответов является связь Привет. При нормальных обстоятельствах сервер отправит 220 ответ «ожидаем ввода», когда соединение установлено. Пользователь должен дождаться этого приветствия, прежде чем отправлять команды. Если сервер не может сразу принять ввод, 120 «ожидаемая задержка» ответ должен быть отправлен немедленно и 220 ответь когда будешь готов. Пользователь будет знать, что не следует вешать трубку, если есть задержка.

Именно поэтому класс FTPClient ожидает ввода от внешней стороны.

2 голосов
/ 24 января 2010

У нас была какая-то Java, которая пыталась подключиться к FTP с устройства, и она необъяснимым образом зависала, используя commons-net / ftp Так же, как то, что вы видите. После долгих поисков я где-то нашел сообщение об ошибке, указывающее, что это недостаток в commons-net / ftp. Ошибка возникает, когда вы ожидаете ответа, и сеть отключается (у нас была нестабильная беспроводная связь). Как только это произошло, оно оказалось в ожидании, которое так и не вернулось.

Решение, которое мы нашли, к сожалению, заключается в использовании другой библиотеки. Есть много там, но это тот, который мы использовали. http://www.enterprisedt.com/products/edtftpj/overview.html

...