公共网ftp死锁?

我有一个进程,应该每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  (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  (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秒内超时?

是的,不。

连接将在十秒内超时,假设连接不起作用,但是连接可能确实有效,现在它正在尝试从套接字读取数据,最有可能将初始FTP helo序列排除在外[1]。 实际上,查看connectAction ()的javadoc ,这是你的stacktrace被卡住的地方,这正是它正在做的事情。

您可以尝试在调用connect之前设置数据超时 ,这样它实际上可能会以您期望的方式失败。 如果这不起作用,您很可能需要使用apache-commons引发错误 。 这个错误几乎肯定是你所看到的问题。

[1]根据RFC959:

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

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

我们有一些java试图从一个设备FTP,它会莫名其妙地使用commons-net / ftp挂起。 就像你所看到的一样。 经过大量的搜索,我发现了一个错误报告,表明它是一个带有commons-net / ftp的漏洞。 当你在等待响应时,网络出现故障(我们有无线网卡),就会出现这种缺陷。 一旦发生这种情况,就会陷入一场永不复发的等待。

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