【问题标题】:commons net ftp deadlock?commons net ftp死锁?
【发布时间】:2011-01-08 16:21:33
【问题描述】:

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

【问题讨论】:

    标签: java ftp apache-commons


    【解决方案1】:

    是的,也不是。

    连接将在十秒内超时,假设连接没有工作,但是连接可能工作了,现在它正在尝试从套接字读取数据,最有可能得到初始的 FTP helo 序列的方式[1]。确实,查看the javadoc for connectAction(),这是您的堆栈跟踪卡住的地方,这正是它正在做的事情。

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

    [1] 根据 RFC959:

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

    这就是 FTPClient 类等待来自外部的输入的原因。

    【讨论】:

    • @pstanton:谢谢,我已经更新了答案以包含一个错误链接。
    • 我记得我把setDataTimeout 调用放在connect 调用之后,因为我认为它可能类似于setSoTimeout 调用,其文档声明仅在connect 之后使用。已将setDataTimeout 向上移动,希望这能解决。谢谢。
    • @pstanton:可能……但你需要测试一下,因为我不能肯定回答。
    【解决方案2】:

    我们有一些 java 正在尝试从设备进行 FTP,并且使用 commons-net/ftp 会莫名其妙地挂起。就像你所看到的一样。经过大量搜索,我在某处发现了一个错误报告,表明这是 commons-net/ftp 的一个缺陷。当您等待响应并且网络出现故障(我们有不稳定的无线)时,就会出现该缺陷。一旦发生这种情况,它就会陷入永远不会回来的等待。

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

    【讨论】:

    • 你可以通过明确设置数据超时来解决这个问题……或者使用不同的库;-)
    猜你喜欢
    • 1970-01-01
    • 2013-06-17
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 2018-07-07
    • 2017-11-05
    • 2010-11-09
    • 2013-04-24
    相关资源
    最近更新 更多