Java 公用网络ftp死锁?

Java 公用网络ftp死锁?,java,ftp,apache-commons,Java,Ftp,Apache Commons,我有一个进程,应该每5分钟将一个文件ftp到一个远程位置 它似乎已经被卡住了好几个小时,并且没有发送文件 我进行了线程转储以查看发生了什么,这是我线程的状态: "SPPersister" prio=6 tid=0x03782400 nid=0x16c4 runnable [0x0468f000..0x0468fd14] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Nat

我有一个进程,应该每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)
        ...
“SPPersister”优先级=6 tid=0x03782400 nid=0x16c4可运行[0x0468f000..0x0468fd14]
java.lang.Thread.State:可运行
位于java.net.SocketInputStream.socketRead0(本机方法)
位于java.net.SocketInputStream.read(未知源)
位于sun.nio.cs.StreamDecoder.readBytes(未知源)
位于sun.nio.cs.StreamDecoder.implRead(未知源)
at sun.nio.cs.StreamDecoder.read(未知源)
-锁定(java.io.InputStreamReader)
位于java.io.InputStreamReader.read(未知源)
位于java.io.BufferedReader.fill(未知源)
位于java.io.BufferedReader.readLine(未知源)
-锁定(java.io.InputStreamReader)
位于java.io.BufferedReader.readLine(未知源)
位于org.apache.commons.net.ftp.ftp.\uu getReply(ftp.java:294)
在org.apache.commons.net.ftp.ftp.\u connectAction\uu(ftp.java:364)
在org.apache.commons.net.ftp.FTPClient.\u connectAction.\u(FTPClient.java:540)
位于org.apache.commons.net.SocketClient.connect(SocketClient.java:178)
位于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);
FTPClient client=new FTPClient();
客户端.setConnectTimeout(10000);
client.connect(主机);// 是的,也不是

连接将在十秒钟内超时,假设连接不起作用,但连接可能起作用,现在它正试图从套接字读取数据,很可能会使初始FTP helo序列中断[1]。事实上,看看stacktrace被卡住的地方,这正是它所做的

您可以在调用connect之前尝试设置,这样它实际上可能会以您预期的方式失败。如果这不起作用,你很可能需要这样做。几乎可以肯定,这就是你所看到的问题

[1] 根据RFC959:

一组重要的信息性回复是连接 问候语。在正常情况下,服务器将发送220 连接完成后,回复“等待输入”。这个 用户应等待此问候语,然后再发送任何信息 命令。如果服务器无法立即接受输入,则 120“预期延迟”回复应立即发送,并发送220 准备好后回复。如果出现问题,用户将知道不要挂断 这是一个延误


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

我们有一些java试图从一个设备上进行FTP,使用commons net/FTP它会莫名其妙地挂起。就像你看到的一样。经过大量搜索,我在某处发现了一个bug报告,表明这是commons net/ftp的一个缺陷。当您在等待响应时,网络出现故障(我们使用的是flaky wireless)。一旦发生这种情况,它就陷入了一种再也没有回来的等待之中


不幸的是,我们找到的解决方案是使用不同的库。外面有很多,但这是我们用过的

听起来像是这个bug:@pstanton:谢谢,我已经更新了答案,添加了一个bug的链接。我记得我把
setDataTimeout
调用放在
connect
调用之后,因为我想这可能像
setotimeout
调用,它的文档状态只能在
connect
之后使用。已经向上移动了
setDataTimeout
,希望这能解决问题。thx.@pstanton:可能……但您需要测试它,因为我无法确定答案。您可能可以通过显式设置datatimeout来解决这个问题……或者使用其他库;-)