2010-01-24 74 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