隨筆 - 312, 文章 - 14, 評(píng)論 - 1393, 引用 - 0
          數(shù)據(jù)加載中……

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

          本文為原創(chuàng),如需轉(zhuǎn)載,請(qǐng)注明作者和出處,謝謝! 

          上一篇:Java網(wǎng)絡(luò)編程從入門到精通(27):關(guān)閉服務(wù)端連接

          ServerSocket對(duì)象相關(guān)的信息有兩個(gè):綁定端口和綁定IP地址。綁定端口可以通過(guò)getLocalPort方法獲得。綁定IP地址可以通過(guò)getInetAddress方法獲得。

          一、getLocalPort方法

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

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

          2.       ServerSocket對(duì)象綁定了一個(gè)固定的端口,getLocalPort方法返回這個(gè)固定端口。

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

          getLocalPort方法的定義如下:

          public int getLocalPort()

          getLocalPort方法主要是為這些匿名端口而準(zhǔn)備的。下面的代碼演示了ServerSocket對(duì)象產(chǎn)生隨機(jī)端口的過(guò)程:

          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());
                  }
              }
          }

          運(yùn)行結(jié)果:

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

          在大多數(shù)時(shí)候ServerSocket對(duì)象都會(huì)綁定一個(gè)固定的端口。但有時(shí)客戶端只需要和服務(wù)端進(jìn)行短暫的連接,這時(shí)就可以使用匿名端口。如我們經(jīng)常用的FTP服務(wù)就是如此。

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

          1.  主動(dòng)模式

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

           

          圖1  主動(dòng)模式的工作原理


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

          2. 被動(dòng)模式

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

          圖2  被動(dòng)模式的工作原理

           

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

          二、getInetAddress方法

          getInetAddress可以得到ServerSocket對(duì)象綁定的IP地址。如果ServerSocket對(duì)象未綁定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());   

          運(yùn)行結(jié)果:

           

          192.168.18.100

          三、getLocalSocketAddress方法

          這個(gè)方法其實(shí)是將getLocalPortgetInetAddress方法的功能集成到了一起。也就是說(shuō),使用getLocalSocketAddress方法可以同時(shí)得到綁定端口和綁定IP地址。這個(gè)方法返回了一個(gè)SocketAddress對(duì)象。SocketAddress類是一個(gè)抽象類,要想分別得到端口和IP地址,必須將SocketAddress對(duì)象轉(zhuǎn)換成InetSocketAddress對(duì)象(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());

          運(yùn)行結(jié)果:

          /192.168.18.100:1234
          192.168.18.100
          1234

          下一篇:Java網(wǎng)絡(luò)編程從入門到精通(29):服務(wù)端Socket的選項(xiàng)





          Android開(kāi)發(fā)完全講義(第2版)(本書(shū)版權(quán)已輸出到臺(tái)灣)

          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) 評(píng)論(1)  編輯  收藏 所屬分類: java 原創(chuàng)網(wǎng)絡(luò)編程

          評(píng)論

          # re: Java網(wǎng)絡(luò)編程從入門到精通(28):獲取ServerSocket信息的方法及FTP原理  回復(fù)  更多評(píng)論   

          跟著學(xué)習(xí)一下不錯(cuò)
          2009-08-12 14:43 | Bobo小說(shuō)網(wǎng)
          主站蜘蛛池模板: 河西区| 古丈县| 勃利县| 肃南| 资中县| 舒城县| 华坪县| 顺平县| 旺苍县| 彝良县| 开鲁县| 林西县| 五大连池市| 阿鲁科尔沁旗| 静宁县| 沙田区| 张家川| 东台市| 调兵山市| 海林市| 秀山| 富源县| 杂多县| 黔南| 达孜县| 嘉鱼县| 阿拉善右旗| 曲松县| 西昌市| 辽阳县| 独山县| 益阳市| 商洛市| 射阳县| 安丘市| 会东县| 淳化县| 山阳县| 广宗县| 筠连县| 太保市|