linux的ftp下载假死,记一次commons-net FTP上传下载卡死
在利用apache的commons-net包,做FTP上傳下載時,碰到了一個問題:在默認配置下,傳輸大文件會卡死。
commons-net的maven依賴:
commons-net
commons-net
3.6
在翻閱了官方文檔后,發現了一段描述,原文如下:
Control channel keep-alive feature:
Please note: this does not apply to the methods where the user is responsible for writing or reading the data stream, i.e. retrieveFileStream(String) , storeFileStream(String) and the other xxxFileStream methods
During file transfers, the data connection is busy, but the control connection is idle. FTP servers know that the control connection is in use, so won't close it through lack of activity, but it's a lot harder for network routers to know that the control and data connections are associated with each other. Some routers may treat the control connection as idle, and disconnect it if the transfer over the data connection takes longer than the allowable idle time for the router.
One solution to this is to send a safe command (i.e. NOOP) over the control connection to reset the router's idle timer. This is enabled as follows:
ftpClient.setControlKeepAliveTimeout(300); // set timeout to 5 minutes
This will cause the file upload/download methods to send a NOOP approximately every 5 minutes. The following public methods support this:
This feature does not apply to the methods where the user is responsible for writing or reading the data stream, i.e. retrieveFileStream(String) , storeFileStream(String) and the other xxxFileStream methods. In such cases, the user is responsible for keeping the control connection alive if necessary.
The implementation currently uses a CopyStreamListener which is passed to the Util.copyStream(InputStream, OutputStream, int, long, CopyStreamListener, boolean) method, so the timing is partially dependent on how long each block transfer takes.
如上描述,commons-net有一個重要特性,Control channel keep-alive特性。在大文件傳輸時,由于網絡網速比較低,傳輸較慢,在傳輸期間,data connection是在活動的,但是 control connection是空閑的。對于FTP服務器來說,它知道網絡是有活動的。但是對于一些路由器來說,它們將data connection和control connection視為相互關聯的,發現control connection空閑就將網絡關閉。
解決方法是發一個no-op command,類似心跳請求來維持網絡,防止路由器將網絡切斷。但是對于xxFileStream的方法是不適用的,在一開始編碼時正好使用該方法,導致卡死的情況,可以改用retrieveFile和storeFile方法替換。另外根據業務情況可以添加一些超時配置:
# 默認超時時間(ms)
defaultTimeout: 3000
# 連接超時時間 (ms)
connectTimeout: 3000
# 數據傳輸超時時間(ms)
dataTimeout: 3000
# 每隔xx秒,像FTP服務器發送一次心跳
controlKeepAliveTimeout: 60
總結:一開始使用commons-net包,很容易碰到的一個坑,此處記一下,希望能幫助到大家,謝謝。
總結
以上是生活随笔為你收集整理的linux的ftp下载假死,记一次commons-net FTP上传下载卡死的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DOM常用的四大对象是什么?
- 下一篇: JAVA笔记--打印byte数组