Java網(wǎng)絡(luò)編程從入門到精通(28):獲取ServerSocket信息的方法及FTP原理
上一篇: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ì)象的綁定端口為0,getLocalPort方法返回一個(gè)隨機(jī)的端口(這類端口被稱為匿名端口)。
getLocalPort方法的定義如下:
getLocalPort方法主要是為這些匿名端口而準(zhǔn)備的。下面的代碼演示了ServerSocket對(duì)象產(chǎn)生隨機(jī)端口的過(guò)程:
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 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è)端口:21和20 (這兩個(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)模式中,在傳送命令和數(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)模式的工作原理。
現(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.0。getInetAddress方法的定義如下:
下面的代碼演示了getInetAddress的使用方法:
serverSocket.bind(new InetSocketAddress("192.168.18.100", 0));
System.out.println(serverSocket.getInetAddress().getHostAddress());
運(yùn)行結(jié)果:
三、getLocalSocketAddress方法
這個(gè)方法其實(shí)是將getLocalPort和getInetAddress方法的功能集成到了一起。也就是說(shuō),使用getLocalSocketAddress方法可以同時(shí)得到綁定端口和綁定IP地址。這個(gè)方法返回了一個(gè)SocketAddress對(duì)象。SocketAddress類是一個(gè)抽象類,要想分別得到端口和IP地址,必須將SocketAddress對(duì)象轉(zhuǎn)換成InetSocketAddress對(duì)象(InetSocketAddress類是從SocketAddress類繼承的)。getLocalSocketAddress方法的定義如下:
下面的代碼演示了getLocalSocketAddress的使用方法。
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
下一篇: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ò)編程