2010-01-24 159 views
4

我有一个过程,应该每5分钟将文件ftp到远程位置。commons net 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秒内超时?

回答

3

是的,没有。

假设连接不起作用,连接将在10秒内超时,但连接可能已经工作,现在它试图从套接字读取数据,最有可能获得最初的FTP helo序列不受影响[1]。事实上,看着你的堆栈跟踪卡的the javadoc for connectAction(),这正是它正在做的。

在调用连接之前,您可以尝试设置the data timeout,这样它可能实际上会以您期望的方式失败。如果这不起作用,您很可能需要raise a bug with apache-commonsThis bug几乎肯定是你所看到的问题。

[1]根据RFC959:信息性的

一个重要组答复是连接 问候。在正常情况下,当连接完成时,服务器将发送一个220“等待输入”的回复。在发送任何 命令之前, 用户应等待此问候消息。如果服务器无法立即接受输入,则应立即发送120“预期延迟”答复,并在准备就绪时发送220 答复。如果 是延迟,那么用户将知道不挂断电话。

这就是为什么FTPClient类正在等待来自外部的输入。

+0

听起来像这个bug:http://www.mail-archive.com/[email protected]/msg55067.html – pstanton 2010-01-24 00:58:12

+0

@pstanton:谢谢,我已经更新了答案,以包含链接错误。 – 2010-01-24 01:02:18

+0

我记得我在'connect'调用之后放了'setDataTimeout'调用,因为我认为它可能像'setSoTimeout'调用的文档声明只在'connect'后面使用。已经移动了'setDataTimeout',希望能够解决这个问题。谢谢。 – pstanton 2010-01-24 01:17:33

2

我们有一些java试图从设备FTP,它会莫名其妙地挂在使用commons-net/ftp。就像你所看到的一样。经过相当多的搜索后,我发现了一个错误报告,表明它是commons-net/ftp的缺陷。当你等待回应时,这个缺陷就会发生,网络就会停止运转(我们有无线的无线网络)。一旦发生这种情况,它就会陷入从未回来的等待状态。

我们发现的解决方案很不幸地使用不同的库。这里有很多,但这是我们使用的。 http://www.enterprisedt.com/products/edtftpj/overview.html

+0

你可以通过明确设置datatimeout或通过使用不同的库来解决这个问题;-) – 2010-01-24 01:04:27