国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

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

2019-11-17 04:00:35
字體:
來源:轉載
供稿:網友
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程序員,上班那點事》紀念帖
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 安福县| 若尔盖县| 黑龙江省| 吴江市| 多伦县| 布尔津县| 云龙县| 永定县| 双柏县| 鹤壁市| 景德镇市| 寿光市| 班玛县| 黎城县| 葫芦岛市| 齐河县| 吉隆县| 五莲县| 瑞昌市| 伊宁县| 广安市| 公主岭市| 民乐县| 银川市| 潜江市| 都江堰市| 车致| 福鼎市| 盘锦市| 淮南市| 威海市| 海宁市| 斗六市| 马公市| 通山县| 陇川县| 稷山县| 如皋市| 凤城市| 蚌埠市| 梅河口市|