commons net ftp死锁? [英] commons net ftp deadlock?

查看:150
本文介绍了commons net ftp死锁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序,应该每隔5分钟将文件ftp到远程位置。



它似乎已经停留了数小时,并且hasn发送文件。

我使用线程转储来查看发生了什么,这是我的线程状态:


$
pre $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ b在java.net.SocketInputStream.socketRead0(本地方法)$ b $在java.net.SocketInputStream.read(未知源)
在sun.nio.cs.StreamDecoder.readBytes(未知源)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
- locked< 0x239ebea0> (java.io.InputStreamReader)
在java.io.InputStreamReader.read(未知源)
在java.io.BufferedReader.fill(未知源)
在java.io.BufferedReader .readLine(未知来源)
- 锁定< 0x239ebea0> (a java.io.InputStreamReader)
在java.io.BufferedReader.readLine(未知源)
在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); //< - 卡在这里
client.setDataTimeout(20000);
client.setSoTimeout(20000);
client.login(user,pass);
client.changeWorkingDirectory(dir);

不应该在10秒内超时连接吗?



连接将在10秒内超时,假设连接不起作用,但连接可能已经工作了,现在它试图从套接字读取数据,最有可能获得最初的FTP helo序列[1]。确实,查看 javadoc对于 connectAction (),这是您的堆栈跟踪卡住的地方,这正是它正在做的事情。



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



根据RFC959:


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


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

I have a process that is supposed to ftp a file to a remote location every 5 minutes.

It seems to have become stuck for a number of hours and hasn't been sending files.

I took a thread dump to see what was going on and this is the state of my thread:

"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)
        ...

I am using the following code to connect:

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);

Shouldn't the connection attempt have timed out within 10 seconds?

解决方案

Yes, and no.

The connect will have timed out within ten seconds, assuming that the connect did not work, however the connect probably did work, and now it is trying to read data from the socket, most likely to get the initial FTP helo sequence out of the way[1]. Indeed, looking at the javadoc for connectAction(), which is where your stacktrace is stuck, that is exactly what it is doing.

You could try setting the data timeout before you call connect, that way it might actually fail in the way that you expect. If this doesn't work, you will most likely need to raise a bug with apache-commons. This bug is almost certainly the issue that you are seeing.

[1] According to RFC959:

One important group of informational replies is the connection greetings. Under normal circumstances, a server will send a 220 reply, "awaiting input", when the connection is completed. The user should wait for this greeting message before sending any commands. If the server is unable to accept input right away, a 120 "expected delay" reply should be sent immediately and a 220 reply when ready. The user will then know not to hang up if there is a delay.

That is why the FTPClient class is awaiting input from the foreign side.

这篇关于commons net ftp死锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆