隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0

          導航

          <2009年8月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          公告

          關注我的新浪微博

          我的著作









          常用鏈接

          留言簿(126)

          我參與的團隊

          隨筆分類(818)

          隨筆檔案(310)

          文章分類(1)

          文章檔案(8)

          相冊

          ADSL、3G查詢

          CSDN

          eclipse

          ibm

          Java EE

          Linux

          Web

          云服務

          代理網站

          關注的網站

          協議

          喜歡的Blog

          國內廣告平臺

          圖書出版

          在線培訓

          開發工具

          微博客戶端

          手機鈴聲

          操作系統

          • ReactOS
          • 一個與windowXP/2003兼容的操作系統

          數學

          文件格式

          源碼資源

          移動(Mobile)

          編程語言

          英語學習

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 1974686
          • 排名 - 6

          最新評論

          閱讀排行榜

          評論排行榜

          Java網絡編程從入門到精通(28):獲取ServerSocket信息的方法及FTP原理

          本文為原創,如需轉載,請注明作者和出處,謝謝! 

          上一篇:Java網絡編程從入門到精通(27):關閉服務端連接

          ServerSocket對象相關的信息有兩個:綁定端口和綁定IP地址。綁定端口可以通過getLocalPort方法獲得。綁定IP地址可以通過getInetAddress方法獲得。

          一、getLocalPort方法

          getLocalPort方法的返回值可分為以下三種情況:

          1.       ServerSocket對象未綁定端口,getLocalPort方法的返回值為-1

          2.       ServerSocket對象綁定了一個固定的端口,getLocalPort方法返回這個固定端口。

          3. ServerSocket對象的綁定端口為0getLocalPort方法返回一個隨機的端口(這類端口被稱為匿名端口)。

          getLocalPort方法的定義如下:

          public int getLocalPort()

          getLocalPort方法主要是為這些匿名端口而準備的。下面的代碼演示了ServerSocket對象產生隨機端口的過程:

          package server;

          import java.net.*;

          public class RandomPort
          {
              
          public static void main(String[] args) throws Exception
              {
                  
          for (int i = 1; i <= 5; i++)
                  {
                      System.out.print(
          "Random Port" + i + "");
                      System.out.println(
          new ServerSocket(0).getLocalPort());
                  }
              }
          }

          運行結果:

          Random Port1:1397
          Random Port2:
          1398
          Random Port3:
          1399
          Random Port4:
          1400
          Random Port5:
          1401

          在大多數時候ServerSocket對象都會綁定一個固定的端口。但有時客戶端只需要和服務端進行短暫的連接,這時就可以使用匿名端口。如我們經常用的FTP服務就是如此。

          FTP服務器一般分為兩種工作模式:主動模式(Port模式)和被動模式(PASV模式)。在這里主動和被動都是指FTP服務器。

          1.  主動模式

          在主動模式中,FTP服務器綁定了兩個端口:2120 (這兩個端口是默認值,可以設成別的端口)。其中21端口負責客戶端和服務器之間的命令傳送。一開始,由客戶端主動連接服務端的21端口,并且向服務器發送相應的FTP命令。另外一個端口20是負責客戶端和服務端的數據傳送。但要注意,并不是客戶端主動連接服務端的20端口,而是在客戶端創建一個使用匿名端口的服務端連接(在Java中就是創建一個ServerSocket對象,并且綁定端口是0)。然后客戶端通過21端口將這個匿名端口通知服務端。最后,服務端主動連接客戶端的這個匿名端口(所以這種模式叫主動模式,就是服務器主動連接客戶端)。圖1描述主動模式的工作原理。

           

          圖1  主動模式的工作原理


          從圖1可以看出,在主動模式中,在傳送命令和數據時,建立連接的過程是相反的。也就是說,在傳送命令時,由客戶端主動連接服務器的21端口。而傳送數據時,由服務器主動連接客戶端的匿名端口。這種方式是FTP服務器最初的工作模式,但這種模式有很大的局限性。如客戶端通過代理上網,而且未做端口映射。在這種情況下,服務端是無法主動和客戶端建立連接的。因此,這就產生的另一種模式:被動模式。

          2. 被動模式

          被動模式和主動模式在傳送命令的方式上是一樣的。它們的區別就在于數據的傳輸上。被動模式在建立命令傳輸通道后,服務端建立一個綁定到匿名端口的ServerSocket對象。并通過命令傳輸通道將這個匿名端口通知客戶端,然后由客戶端主動連接服務端的這個匿名端口。這對于服務端就是被動的,因此,這種模式叫被動模式。圖2描述了被動模式的工作原理。

          圖2  被動模式的工作原理

           

          現在的大多數FTP客戶端軟件的默認工作模式都是被動模式。因此,這種模式可以克服防火墻等的限制,并且客戶端不需要有固定IP。但這種模式也有它的缺點,這就是在服務端要為客戶開大量的端口(大多數FTP服務器開的端口范圍是1024 ~ 5000,但有的服務器的范圍達到1024 ~ 65535)。這對于服務器來說存在著一定的安全隱患。因此,如果可能的話,最好還是采用主動模式。

          二、getInetAddress方法

          getInetAddress可以得到ServerSocket對象綁定的IP地址。如果ServerSocket對象未綁定IP地址,返回0.0.0.0getInetAddress方法的定義如下:

           public InetAddress getInetAddress()

          下面的代碼演示了getInetAddress的使用方法:

           

          ServerSocket serverSocket = new ServerSocket();
          serverSocket.bind(
          new InetSocketAddress("192.168.18.100"0));   
          System.out.println(serverSocket.getInetAddress().getHostAddress());   

          運行結果:

           

          192.168.18.100

          三、getLocalSocketAddress方法

          這個方法其實是將getLocalPortgetInetAddress方法的功能集成到了一起。也就是說,使用getLocalSocketAddress方法可以同時得到綁定端口和綁定IP地址。這個方法返回了一個SocketAddress對象。SocketAddress類是一個抽象類,要想分別得到端口和IP地址,必須將SocketAddress對象轉換成InetSocketAddress對象(InetSocketAddress類是從SocketAddress類繼承的)。getLocalSocketAddress方法的定義如下:

          public SocketAddress getLocalSocketAddress()

          下面的代碼演示了getLocalSocketAddress的使用方法。

          ServerSocket serverSocket = new ServerSocket();
          serverSocket.bind(
          new InetSocketAddress("192.168.18.100"1234));
          System.out.println(serverSocket.getLocalSocketAddress());
          InetSocketAddress nsa 
          = (InetSocketAddress)serverSocket.getLocalSocketAddress();
          System.out.println( nsa.getAddress().getHostAddress());
          System.out.println( nsa.getPort());

          運行結果:

          /192.168.18.100:1234
          192.168.18.100
          1234

          下一篇:Java網絡編程從入門到精通(29):服務端Socket的選項





          Android開發完全講義(第2版)(本書版權已輸出到臺灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2009-08-12 14:27 銀河使者 閱讀(4804) 評論(1)  編輯  收藏 所屬分類: java 原創網絡編程

          評論

          # re: Java網絡編程從入門到精通(28):獲取ServerSocket信息的方法及FTP原理  回復  更多評論   

          跟著學習一下不錯
          2009-08-12 14:43 | Bobo小說網
          主站蜘蛛池模板: 永修县| 富民县| 桦南县| 柯坪县| 驻马店市| 赣州市| 慈利县| 镇原县| 阿城市| 灌云县| 同江市| 巴彦县| 金湖县| 隆尧县| 富源县| 渝北区| 成武县| 赤峰市| 昔阳县| 水富县| 岳阳市| 诸暨市| 渭南市| 衡阳市| 山东| 资阳市| 嵊州市| 左贡县| 盘锦市| 赤水市| 石林| 资溪县| 旺苍县| 湟源县| 常熟市| 镇江市| 南陵县| 栖霞市| 龙游县| 长丰县| 沁源县|