最近一段時間,因為公司項目的需要,對HTTP協議以及FTP協議都有所了解,并且在基于網絡開放源代碼
基礎上, 能夠完成項目的要求。今天給大家分享下,怎樣建立屬于我們自己的FTP服務器以及FPT客戶端,同時
非常非常感謝 這些開源軟件及其作者為IT行業做出的貢獻,最大程度上至少解放了我們這些IT碼農。且看正文。
本文主要內容:
1、FTP服務端部署---- 基于Android中SwiFTP開源軟件介紹;
2、FTP客戶端部署 --- 基于 ftp4j 開源jar包的客戶端開發;
3、使用步驟 --- 如何測試我們搭建的FTP可操作性。
本文所涉及到的知識、文檔、源代碼照舊會在文章末尾列出。歡迎大家一起學習。
一、 FTP服務端部署
SwiFTP 開源軟件是為Android系統開發,也就是說我們可以將其源代碼嵌入到我們的項目中。當然,對其進行
一定改造還是 必不可少的。這兒只是從感官上對SwiFTP的運行效果圖進行一下說面,以便幫助大家有初步認識:
SwiFTP 資料信息:
Google Download 介紹 : http://code.google.com/p/swiftp/downloads/list
GitHub 介紹 : https://github.com/ppareit/swiftp
Android版本SwiFTP截圖
界面其實很簡單,但是從設計角度分析,SwiFTP框架系統還是值得我們研究的,當然如果你想改造成
屬于自己的 FTP服務器(一般就是改改用戶名、密碼、PWD(起始工作目錄))等,那更得花時間去鉆研了。
二、FTP客戶端部署
接下來,重點介紹我們的主角ftp4j開源jar包,該jar包就是開發我們FTP客戶端核心了。
ftp4j 官網地址: http://www.sauronsoftware.it/projects/ftp4j/ 。對比與AndroidSDK而言,也就是ftp4j
SDK了, 一切的 一切(文檔、源代碼、示例)都可以在官網查詢 。想要了解的同學,至少得保證把首頁給 整明白吧。
1、 ftp4j概要
官網描述如下:
Theftp4jlibraryimplementsaJava full-features FTP client. With ftp4j embedded in your
applicationyou can : FTPsite(directorylistingincluded),create,delete,transfer files
(uploadanddownload) , browsethe remote FTPsite(directorylistingincluded),create,delete,
renameandmoveremotedirectoriesandfiles.
關于FTP連接主要有如下幾種方式:
The ftp4j library can connect the remote FTP server:
· Througha direct TCP/IPconnection. 一般就是直接連接了。
· ThroughaFTP proxy. FTP代理
· Tunnelling through aHTTPproxy. HTTP代理
· ThroughaSOCKS 4/4aproxy.
· ThroughaSOCKS 5 proxy.
· You can add support to otherproxies plugging your own connector, since the ftp4jconnection manager
architecture is modular.
2、主要類簡介
下面根據官網的描述,將該 ftp4j 庫的主要類簡單說明下:
FTPClient類
該類封裝了對FTPCommand的請求操作。例如:連接FTP服務器、進行各種各樣的FTP操作(上傳、下載、
刪除、重命名文件 等)。基本使用流程圖如下:
利用偽代碼描述如下:
//1、登錄至FTPp服務器 mFTPClient.connect(mFTPHost, mFTPPort); //2、請求授權 mFTPClient.login(mFTPUser, mFTPPassword); //3、各種FTP操作 mFTPClient.upload(); mFTPClient.download(); //4、斷開FTP連接 mFTPClient.disconnect();
主要方法:
public java.lang.String []connect(java.lang.Stringhost, intport) throws java.lang.IllegalStateException,
java.io.IOException , FTPIllegalReplyException , FTPException
功能:與FTP服務器主機建立連接 .
參數 :
host- FTP服務器的主機名(host name) 或者 ip地址
port- FTP服務器的監聽端口
返回值 :The server welcome message ,FTP服務器響應消息
拋出異常類型 : (略,參見后文)
public void login(java.lang.Stringusername , java.lang.Stringpassword)
throws java.lang.IllegalStateException,
java.io.IOException,FTPIllegalReplyException, FTPException
功能:根據用戶名以及密碼登錄FTP服務器
參數:
username– 登錄FTP服務器的用戶名.
password- 登錄FTP服務器的 密碼
返回值:(無)
拋出異常類型 :(略,參見后文)
public java.lang.String currentDirectory() throws java.lang.IllegalStateException, java.io.IOException,
FTPIllegalReplyException, FTPException
功能 :獲取FTP服務器當前工作目錄。
返回值:FTP服務器當前工作目錄
拋出異常類型 :(略,參見后文)
public longfileSize(java.lang.Stringpath)
功能:獲取指定文件的大小。
參數:
path -- 指定文件所在的路徑,可以是相對路徑或者是絕對路徑。
返回值 : 指定文件的大小,單位為byte.
拋出異常類型 : (略,參見后文)
public void deleteFile(java.lang.Stringpath) throws java.lang.IllegalStateException, java.io.IOException,
FTPIllegalReplyException, FTPException
功能:刪除指定文件
參數:
path -- 指定文件所在的路徑,可以使相對路徑或者是絕對路徑。
返回值:(無)
拋出異常類型 : (略,參見后文)
public void deleteDirectory (java.lang.Stringpath) throws java.lang.IllegalStateException,
java.io.IOException, FTPIllegalReplyException, FTPException
功能:刪除指定文件夾
參數:
path -- 指定文件所在的路徑,可以使相對路徑或者是絕對路徑。
返回值:(無)
拋出異常類型 : (略,參見后文)
publicFTPFile[] list() throws java.lang.IllegalStateException , java.io.IOException,
功能: 獲取當前工作目錄所有文件信息:文件名、文件大小、文件類型(文件或者文件夾)。
返回值:FTPFile[]數組對象 ---- 該文件夾所對應的信息
拋出異常類型 :(略,參見后文)
public java.lang.String[] listNames()
功能:獲取當前工作目錄的所有文件名。
返回值:String[]類型 ----- 所有文件名
拋出異常類型 :(略,參見后文)
public void upload(java.io.Filefile , FTPDataTransferListenerlistener) throws java.lang.IllegalStateException,
java.io.FileNotFoundException, java.io.IOException, FTPIllegalReplyException, FTPException,
FTPDataTransferException,FTPAbortedException
功能 :上傳文件至FTP服務器。 該操作會阻塞當前線程,阻塞會在操作完成后解除 。 該方法可以通過調用
abortCurrentDataTransfer()方法去中斷。默認上傳的文件目錄是當前工作目錄,通過currentDirectory()方法
可以獲得。 注意:不支持上傳文件夾。
參數:file -- 上傳文件的File對象
listener --監聽器 (稍后介紹)
拋出異常類型 :(略,參見后文)
public void download(java.lang.StringremoteFileName, java.io.FilelocalFile,
FTPDataTransferListenerlistener)
throws java.lang.IllegalStateException,java.io.FileNotFoundException,
java.io.IOException, FTPIllegalReplyException, FTPException,
FTPDataTransferException,FTPAbortedException
功能:下載某個文件值指定路徑。該操作會阻塞當前線程,阻塞會在操作完成后解除。該方法可以通過調用
abortCurrentDataTransfer()方法去中斷。注意:不支持下載文件夾。
參數:
remoteFileName- 相對路徑(相對于當前目錄)時則是文件名或者絕對路徑(例如:Linux中以”\”為前綴)
localFile- 本地存放文件的File對象。
listener- 監聽器 (稍后介紹)
拋出異常類型 :(略,參見后文)
public voidabortCurrentDataTransfer(booleansendAborCommand) throws java.io.IOException,
FTPIllegalReplyException
功能:如果存在任何正在進行的文件操作(上傳/下載),該方法會中斷它
參數
sendAborCommand -- true則代表中斷文件操作,并且發送ABORT 命令給FTP服務器
false 代表關閉中斷文件操作,將不會發送任何消息給FTP服務器。
拋出異常類型 :(略,參見后文)
FTPFile 類
該類封裝了FTP服務器中文件的信息,即Model類。
常量字段:
文件對應類型
public static final intTYPE_FILE 文件
public static final intTYPE_DIRECTORY文件夾
public static final intTYPE_LINK 文件引用
主要方法:
public java.util.Date getModifiedDate() 獲取文件最后修改日期。
public int getType() 獲取文件類型。
public long getSize() 獲取文件大小 ,單位為byte。
FTPDataTransferListener Interface
該接口約定了文件傳輸過程中的回調方法類型。我們可以實現該類去監聽每個具體的文件操作過程。
回調接口有:
void started() 回調方法,表示已開始文件傳輸。
void completed() 回調方法,表示文件傳輸已完成。
void aborted() 回調方法,表示文件傳輸已被中斷,可由abortCurrentDataTransfer()觸發。
void failed() 回調方法,表示文件傳輸由于某種錯誤而失敗。
void transferred(intlength) 回調方法,表示本次回調過程中已下載/上傳的文件字節大小。
參數: length--本次回調過程中下載/上傳的文件字節大小。
PS :我們可以累積length大小,以便獲得當前文件已傳輸的字節數。
異常種類:
ftp4j 的自定義共有如下幾種,基本上每個FTP操作,都伴隨著這些異常,因此,我們需要捕獲這些異常信息。
FTPAbortedException
當文件傳輸過程被顯示中斷(例如,調用abortCurrentDataTransfer()方法)時,拋出該異常。
FTPDataTransferException
在文件傳輸過程中,發生任何I/O(例如,無法創建文件流)錯誤,都會拋出 該異常 。
FTPException
封裝了FTP錯誤碼以及錯誤消息的異常類。PS:類似于HTTP錯誤碼以及錯誤消息
常用方法:
public int getCode() 獲取異常發生時,FTP的錯誤碼(錯誤碼字段值具體可見FTPCodes類)
public java.lang.String getMessage() 獲取異常發生時,FTP的錯誤消息。
FTPIllegalReplyException
當FTP服務器以一種非正常的方式---違反了FTP協議的規則響應時,拋出該異常。
FTPListParseException
通過list()方法請求FTP服務時,如果此時FTP服務器的返回的消息不能被正確的解析時,都會拋出該異常。
通過對這些相關知識的學習,足矣利用 ftp4j jar包完成我們簡易卻又充實的專屬我們自己的FTP客戶端了。
接下來,便開始我們的FTP客戶端的開發 。
3、FTP客戶端開發
在功能需求上,開發一個FTP客戶端和開發一個文件選擇器甚至文件管理器基本上沒有任何區別,唯一的區別
只在于數據 來源不同,這個不同會導致功能實踐上更多細節的差異,例如:異常的捕獲、斷點嘗試等。代碼方面
我就不再贅述了,對前面 所介紹類的掌握和理解,應該No Problem了。主要說一下兩點:
①、由于Android4.0不允許在主線程上進行網絡操作,例如:Socket編程,我們的操作必須放在新的線程中。
同 時為了 減少創建線程的開銷,我們試用了線程池去執行每一個FTP操作。
②、試用FTPClient時,不允許上傳/下載文件夾,我也沒有針對這一方面進行更多的開發(具體實現過程大致
為:對文件夾里 的每個文件皆進行上傳/下載操作),有興趣的同學可以看看這篇帖子< 基于ftp4j的FTP客戶端工具 >,
會提升對你對 ftp4j 的使用 認知的。
我們的FTP客戶端主要功能為:
①、顯示特定目錄列表;
②、刪除文件以及文件夾,下載文件;
③、上傳文件。
主要代碼如下:
/** * * @author jun.qin * {@link} http://blog.csdn.net/qinjuning * */ public class FtpMainActivity extends Activity implements OnClickListener { private static String TAG = CopyOfFtpMainActivity.class.getName(); private CmdFactory mCmdFactory; private FTPClient mFTPClient; private ExecutorService mThreadPool; @Override protected void onDestroy() { mDameonRunning = false ; Thread thread = new Thread(mCmdFactory.createCmdDisConnect()) ; thread.start(); //等待連接中斷 try { thread.join(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } mThreadPool.shutdownNow(); super.onDestroy(); } //put線程池中執行 private void executeConnectRequest() { mThreadPool.execute(mCmdFactory.createCmdConnect()); } private void executeDisConnectRequest() { mThreadPool.execute(mCmdFactory.createCmdDisConnect()); } private void executePWDRequest() { mThreadPool.execute(mCmdFactory.createCmdPWD()); } private void executeLISTRequest() { mThreadPool.execute(mCmdFactory.createCmdLIST()); } //創建FtpCmd的工廠類 public class CmdFactory { public FtpCmd createCmdConnect() { return new CmdConnect(); } public FtpCmd createCmdDisConnect() { return new CmdDisConnect(); } } //繼承了Runnable接口 public abstract class FtpCmd implements Runnable { public abstract void run(); } //連接命令 public class CmdConnect extends FtpCmd { @Override public void run() { boolean errorAndRetry = false ; //根據不同的異常類型,是否重新捕獲 try { String[] welcome = mFTPClient.connect(mFTPHost, mFTPPort); if (welcome != null) { for (String value : welcome) { logv("connect " + value); } } mFTPClient.login(mFTPUser, mFTPPassword); mHandler.sendEmptyMessage(MSG_CMD_CONNECT_OK); }catch (IllegalStateException illegalEx) { illegalEx.printStackTrace(); errorAndRetry = true ; }catch (IOException ex) { ex.printStackTrace(); errorAndRetry = true ; }catch (FTPIllegalReplyException e) { e.printStackTrace(); }catch (FTPException e) { e.printStackTrace(); errorAndRetry = true ; } if(errorAndRetry && mDameonRunning){ mHandler.sendEmptyMessageDelayed(MSG_CMD_CONNECT_FAILED, 2000); } } } public class CmdDisConnect extends FtpCmd { @Override public void run() { if (mFTPClient != null) { try { mFTPClient.disconnect(true); } catch (Exception ex) { ex.printStackTrace(); } } } } //下載命令 public class CmdDownLoad extends AsyncTask<Void, Integer, Boolean> { @Override protected Boolean doInBackground(Void... params) { try { String localPath = getParentRootPath() + File.separator + mFileList.get(mSelectedPosistion).getName(); mFTPClient.download( mFileList.get(mSelectedPosistion).getName(), new File(localPath), new DownloadFTPDataTransferListener(mFileList.get( mSelectedPosistion).getSize())); } catch (Exception ex) { ex.printStackTrace(); return false; } return true; } protected void onPostExecute(Boolean result) { toast(result ? "下載成功" : "下載失敗"); progressDialog.dismiss(); } } }
三,使用方法說明
前提條件, 確保兩臺手機分別安裝FTP服務端,FTP客戶端 ,并且能連接上WIFI網絡。
第一步:運行FTP服務器SwiFtp,輸入基本信息(端口、用戶名、密碼),同時確保FTP服務器成功開啟 。如圖:
配置FTP服務器信息 FTP服務器狀態
第二步:運行FTP客戶端,填寫FTP驗證時的資料(即第一步輸入信息)后,連接FTP服務器即可。如圖:

最后,本文所涉及到的所有資料以及文章中示例的源代碼的下載地址為:
http://download.csdn.net/detail/qinjuning/5034873
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
