Java的FTP協議級用戶端實現詳解

來源:互聯網
上載者:User
10.2.4.3 例子3:網路應用程式層協議的開發        清華大學出版社《Java程式員,上班那點事兒》作者:鐘聲——第10章《高手有多高菜鳥有多菜》部分節選。
       大家也許都用過FTP上傳下載工具,比如“LeapFTP”這個工具是一個很方便的FTP伺服器上傳下載工具,。這個工具很方便,輸入使用者名稱密碼以後,就可以看到FTP伺服器端的檔案清單,便於進行上傳與下載操作。

        你是否試過自己用Java編寫一個FTP的檔案上傳與下載應用程式?
        Java也可以開發出這樣的程式來,並不複雜,我們先看看,利用Java的FTP類工具包製作FTP應用程式的開發是怎麼做的,請看如下程式:
 import sun.net.*;
import sun.net.ftp.*;public class FTP {
   
    public static void main(String[] args) {
     
        String server="192.168.0.12";   //輸入的FTP伺服器的IP地址
        String user="useway";            //登入FTP伺服器的使用者名稱
        String password="!@#$%abce";   //登入FTP伺服器的使用者名稱的口令
        String path="/home/useway";      //FTP伺服器上的路徑
       
        try {
         
          FtpClient ftpClient=new FtpClient();  //建立FtpClient對象
          ftpClient.openServer(server);        //串連FTP伺服器
          ftpClient.login(user, password);     //登入FTP伺服器
         
          if (path.length()!=0) ftpClient.cd(path);
         
          TelnetInputStream is=ftpClient.list();
          int c;
          while ((c=is.read())!=-1) {
             System.out.print((char)c);
          }
          is.close();
          ftpClient.closeServer();//退出FTP伺服器
        }
        catch(Exception ex){
        }
     }
}        如果你感興趣的話,可以自己寫一個這個程式,當本程式運行以後,我們看到的情況,列出了伺服器端程式的目錄內容。


         這個程式是一個簡單的得到FTP伺服器端檔案清單的程式,但不要誤會,這個程式可稱不上“網路應用程式層協議”程式的開發!
        這個程式僅僅是利用“sun.net.*;”和“sun.net.ftp.*;”中的相關類進行的對FTP端的操作的,我們根本沒有利用Java的Socket的在網路層面向FTP伺服器端發送任何請求,而是通過Java提供的工具包,向伺服器端發送的連結請求。
        利用Java的FTP包來連結FTP伺服器的好處在於我們不需要關心網路層面發送資料的具體細節,而只要調用相應的方法就行了。利用Java的FTP包來連結FTP伺服器的缺點是使開發人員不知道應用程式層協議收發的來龍去脈,搞不清楚其中原理,對底層資料的把握程度非常弱。
         講到這裡有程式員會問:“那麼FTP在網路層面和PC與伺服器間是如何互動的呢?”,好,就給大家列出FTP協議互動過程。

請看下面的一段FTP協議互動的例子:
 FTP伺服器: 220 (vsFTPd 2.0.1)
FTP用戶端: USER useway
FTP伺服器: 331 Please specify the password.
FTP用戶端: PASS !@#$%abce
FTP伺服器: 230 Login successful.
FTP用戶端: CWD /home/useway
FTP伺服器: 250 Directory successfully changed.
FTP用戶端: EPSV ALL
FTP伺服器: 200 EPSV ALL ok.
FTP用戶端: EPSV
FTP伺服器: 229 Entering Extended Passive Mode (|||62501|)
FTP用戶端: LIST
FTP伺服器: 150 Here comes the directory listing.
FTP伺服器: 226 Directory send OK.
FTP用戶端: QUIT
FTP伺服器: 221 Goodbye.
         以上這段文字其實就是FTP伺服器和FTP用戶端之間相互互動的過程,它們之間傳遞資訊的協議是TCP協議,互相發送的內容就是上面這段文字所寫的內容。        我們下面逐步的去解釋每一句話的含義:

FTP伺服器: 220 (vsFTPd 2.0.1)                                         |說明:連結成功
FTP用戶端: USER useway                                                 |說明:輸入使用者名稱
FTP伺服器: 331 Please specify the password.                |說明:請輸入密碼
FTP用戶端: PASS !@#$%abce                                         |說明:輸入密碼
FTP伺服器: 230 Login successful.                                   |說明:登入成功
FTP用戶端: CWD /home/useway                                    |說明:切換目錄
FTP伺服器: 250 Directory successfully changed.          |說明:目錄切換成功
FTP用戶端: EPSV ALL                                                      |說明:為EPSV被動連結方式
FTP伺服器: 200 EPSV ALL ok.                                        |說明:OK
FTP用戶端: EPSV                                                               |說明:連結
FTP伺服器: 229 Entering Extended Passive Mode (|||62501|)  |說明:被動連結連接埠為62501
FTP用戶端: LIST                                                              |說明:執行LIST顯示檔案清單
FTP伺服器: 150 Here comes the directory listing.      |說明:列表從62501連接埠被發送
FTP伺服器: 226 Directory send OK.                             |說明:發送完成
FTP用戶端: QUIT                                                            |說明:退出FTP
FTP伺服器: 221 Goodbye.                                              |說明:再見
         有了以上文字的內容,我們不需要任何工具也可以得到FTP檔案清單了,不信你跟著我一起做一遍。
          第一步:首先開啟CMD進入DOS命令列模式,鍵入:telnet 192.168.0.1 21[斷行符號]          說明:Telnet 到Ftp伺服器的21連接埠。          執行該命令後,得到的結果。           大家發現什麼問題了嗎?
        提示的內容正好就是,我們上面一段文字的第一句:220 (vsFTPd 2.0.1),這說明FTP伺服器已經接受了我們的連結,已經可以進行下一步操作了。          第二步:將後面的一系列發送內容逐個鍵入: USER useway[斷行符號]
PASS !@#$%abce[斷行符號]
CWD /home/useway[斷行符號]
EPSV ALL[斷行符號]
EPSV[斷行符號]
          得到的結果。           好,這回FTP伺服器給出了一系列的回應,在最後給出了一個新的連接埠號碼"58143"。          第三步:再開啟一個新的CMD視窗,鍵入: telnet 192.168.0.1 58143[斷行符號]          注意,這次Telnet請求連結的伺服器的連接埠號碼是“58143”,是FTP伺服器給我們的一個連結連接埠。連結後,視窗為空白沒有任何提示,。           第四步:回到第一個CMD視窗,鍵入: LIST[斷行符號]          第五步:這時候第二CMD視窗就接收到了檔案清單:          第二個視窗接收到了檔案清單。           第六步:退出操作 QUIT[斷行符號]          執行完成後,失去與主機的連結,。          大家看到了吧,FTP協議就是這樣的一個互動過程,利用系統內建的Telnet工具也可以完成FTP的這些基本命令的操作。如果,你想用Java的Socket完成以上操作就只需要一步一步的按照上述內容發送字串給FTP伺服器端就行了。
       我們下面也給出例子代碼: import java.io.InputStream;  
import java.io.OutputStream;  
import java.net.Socket;  public class FTPClient{
    public static void main(String[] args) throws Exception{  
        Socket socket = new Socket("192.168.0.1",21);  
        InputStream is = socket.getInputStream();  
        OutputStream os = socket.getOutputStream();        //接收初始連結資訊
        byte[] buffer = new byte[100];
        int length = is.read(buffer);
        String s = new String(buffer, 0, length);
        System.out.println(s);
        //發送使用者名稱
        String str = "USER useway/n";
        os.write(str.getBytes());
        //得到傳回值
        length = is.read(buffer);
        s = new String(buffer, 0, length);
        System.out.println(s);       
        //發送密碼
        str = "PASS !@#$%abcd/n";
        os.write(str.getBytes());
//得到傳回值
        length = is.read(buffer);
        s = new String(buffer, 0, length);
        System.out.println(s);
        //發送切換檔案夾指令
        str = "CWD /home/useway/n";
        os.write(str.getBytes());
        //得到傳回值
        length = is.read(buffer);
        s = new String(buffer, 0, length);
        System.out.println(s);
        //設定模式
        str = "EPSV ALL/n";
        os.write(str.getBytes());
        //得到傳回值
        length = is.read(buffer);
        s = new String(buffer, 0, length);
        System.out.println(s);       
        //得到被動監聽資訊
        str = "EPSV/n";
        os.write(str.getBytes());
        //得到傳回值
        length = is.read(buffer);
        s = new String(buffer, 0, length);
        System.out.println(s);
        //取得FTP被動監聽的連接埠號碼
        String portlist=s.substring(s.indexOf("(|||")+4,s.indexOf("|)"));
        System.out.println(portlist);
        //執行個體化ShowList線程類,連結FTP被動監聽連接埠號碼
        ShowList sl=new ShowList();
        sl.port=Integer.parseInt(portlist);
        sl.start();
        //執行LIST命令
        str = "LIST/n";
        os.write(str.getBytes());
        //得到傳回值
        length = is.read(buffer);
        s = new String(buffer, 0, length);
        System.out.println(s);
        //關閉連結
        is.close();
        os.close();
        socket.close();
    }
}
//得到被動連結資訊類,這個類是多線程的
class ShowList extends Thread{
 public int port=0;
    public void run(){
     try{
         Socket socket = new Socket("192.168.0.1",this.port);
         InputStream is = socket.getInputStream();
         OutputStream os = socket.getOutputStream();
         byte[] buffer = new byte[10000];
         int length = is.read(buffer);
         String s = new String(buffer, 0, length);
         System.out.println(s);
            //關閉連結
            is.close();
            os.close();
            socket.close();
     }
     catch(Exception ex){
     }
    }
}         該程式運行後得到的運行結果,基本上和上面的運行效果相同吧,底層又如何,無非是將那些封裝好的方法解開來運行,只要瞭解到了它們啟動並執行規則,我們自己可以開發出一樣的程式來。
  本文是《Java程式員,上班那點事兒》清華大學出版社的一個小節。(轉載請保留這句話,謝謝!)   

《Java程式員,上班那點事兒》:
前言目錄
卓越網銷售連結 
China-pub銷售連結
噹噹網銷售連結《Java程式員,上班那點事》紀念帖

關於下載《Java程式員,上班那點事兒》的電子版

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.