十三章主要內容——Java網絡編程
一、URL類
URL類是java.net包中的一個重要的類,URL的實例封裝著一個統一資源定位符(Uniform Resource Locator),使用URL創建對象的應用程序稱作客戶端程序。
一個URL對象通常包含最基本的三部分信息:協議、地址、資源。
(一)URL的構造方法
URL類通常使用如下的構造方法創建一個URL對象:
public URL(String spec) throws
MalformedURLException
public URL(String protocol, String host,String file) throws MalformedURLException
(二)讀取URL中的資源
URL對象調用
InputStream openStream()
方法可以返回一個輸入流,該輸入流指向URL對象所包含的資源。通過該輸入流可以將服務器上的資源讀入到客戶端。
二、InetAdress類
(一)地址的表示
Internet上的主機有兩種方式表示地址:
1.域名
例如 www.tsinghua.edu.cn
2.IP地址
例如 202.108.35.210
java.net
包中的InetAddress
類對象含有一個Internet主機地址的域名和IP地址,例如 www.sina.com.cn/202.108.37.40 。
(二)獲取地址
1.獲取Internet上主機的地址
可以使用InetAddress
類的靜態方法getByName(String s)
;
獲得一個InetAddress
對象,該對象含有主機地址的域名和IP地址,該對象用如下格式表示它包含的信息:
www.sina.com.cn/202.108.37.40
2.獲取本地機的地址
我們可以使用InetAddress
類的靜態方法getLocalHost()
獲得一個InetAddress
對象,該對象含有本地機的域名和IP地址。
三、套接字
套接字
IP地址標識Internet上的計算機,端口號標識正在計算機上運行的進程(程序)。端口號被規定為一個16位的0~65535之間的整數。
當兩個程序需要通信時,它們可以通過使用Socket類建立套接字對象并連接在一起(端口號與IP地址的組合得出一個網絡套接字)。
(二)客戶端套接字
客戶端的程序使用Socket
類建立負責連接到服務器的套接字對象。
建立連接到服務器的套接字對象:
try{ Socket mysocket=new Socket(“http://192.168.0.78”,1880);}
catch(IOException e)
{ }
與mysocket
相關的方法
getInputStream()
獲得一個輸入流
getOutputStream()
獲得一個輸出流
用getInputStream()
得到的輸入流接到另一個DataInputStream
數據流上
用getOutputStream()
得到的輸出流接到另一個DataOutputStream
數據流上
(三)ServerSocket對象與服務器端套接字
1、
服務器必須建立一個ServerSocket
對象,該對象通過將客戶端的套接字對象和服務器端的一個套接字對象連接起來,從而達到連接的目的。
建立ServerSocket
對象:
try{ ServerSocket serverForClient =new ServerSocket(2010);}catch(IOException e){}
使用方法accept()
將客戶的套接字和服務器端的套接字連接起來,代碼如下所示:
try{ Socket sc= serverForClient .accept();}catch(IOException e){}
所謂“接收”客戶的套接字連接就是accept()
方法會返回一個和客戶端Socket
對象相連接的Socket
對象。
2、
客戶端的套接字獲得的輸入\輸出流和服務器端的套接字獲得的輸出\輸入流互相連接
(四)使用多線程技術
為了防止堵塞線程,服務器端收到一個客戶的套接字后,就應該啟動一個專門為該客戶服務的線程。
在下面的例子4中,客戶使用Socket
類不帶參數的構造方法Socket()
創建一個套接字對象,該對象需調用
public void connect(SocketAddress endpoint) throws IOException
請求和參數SocketAddress
指定地址的套接字建立連接。
為了使用connect
方法,可以使用SocketAddress
的子類InetSocketAddress
創建一個對象,InetSocketAddress
的構造方法是:
InetSocketAddress(InetAddress addr, int port)
四、UDP數據報
基于UDP的通信和基于TCP的通信不同,基于UDP的信息傳遞更快,但不提供可靠性保證。
基于UDP通信的基本模式是:
1.將數據打包,稱為數據包(好比將信件裝入信封一樣),然后將數據包發往目的地。
2.接受別人發來的數據包(好比接收信封一樣),然后查看數據包中的內容。
(一)發送數據包
1.用DatagramPacket
類將數據打包,即用DatagramPacket
類創建一個對象,稱為數據包。用DatagramPacket
的以下兩個構造方法創建待發送的數據包:
DatagramPacket(byte data[],int length,InetAddtress address,int port)
DatagramPack(byte data[],int offset,int length,InetAddtress address,int port)
2.用DatagramSocket
類的不帶參數的構造方法:DatagramSocket()
創建一個對象,該對象負責發送數據包。例如:
DatagramSocket mail_out=new DatagramSocket();
mail_out.send(data_pack);
(二)接收數據包
1. 首先用DatagramSocket
的另一個構造方法DatagramSocket(int port)
創建一個對象,其中的參數必須和待接收的數據包的端口號相同。例如,如果發送方發送的數據包的端口是5666
,那么如下創建DatagramSocket
對象:
DatagramSocket mail_in=new DatagramSocket(5666);
2. 然后對象mail_in
使用方法receive(DatagramPacket pack)
接受數據包。
3.用 DatagramPack
類的另外一個構造方法: DatagramPack(byte data[],int length)
創建一個數據包,用于接收數據包,例如:
byte data[]=new byte[100];int length=90;DatagramPacket pack=new DatagramPacket(data,length);mail_in.receive(pack);
該數據包pack將接收長度是length字節的數據放入data。
五、廣播數據報
廣播數據報涉及到地址和端口。
廣播數據報是一種較新的技術,要廣播或接收廣播的主機都必須加入到同一個D類地址。
六、Java 遠程調用(RMI)
Java遠程調用,RMI(Remote Method Invocation)
是一種分布式技術,使用RMI可以讓一個虛擬機(JVM)上的應用程序請求調用位于網絡上另一處的JVM上的對象方法。習慣上稱發出調用請求的虛擬機(JVM)為(本地)客戶機,稱接受并執行請求的虛擬機(JVM)為(遠程)服務器。
(一)遠程對象及其代理
1.遠程對象:
駐留在(遠程)服務器上的對象是客戶要請求的對象,稱作遠程對象。
2.代理與存根(Stub):
代理的特點是它與遠程對象實現了相同的接口。
存根(Stub):一種特殊的字節碼,并讓這個存根產生的對象為作為遠程對象的代理。
3.Remote接口
RMI為了標識一個對象是遠程對象,即可以被客戶請求的對象,要求遠程對象必須實現java.rmi包中的Remote接口,也就是說只有實現該接口的類的實例才被RMI認為是一個遠程對象。
(二)RMI的設計細節
1.擴展Remote接口
定義一個接口是java.rmi
包中Remote
的子接口,即擴展Remote接口。
RemoteSubject.java
2.遠程對象
創建遠程對象的類必須要實現Remote接口,RMI使用Remote接口來標識遠程對象,但是Remote中沒有方法,因此創建遠程對象的類需要實現Remote接口的一個子接口。RemoteConcreteSubject.java
3.存根(Stub)與代理:RMI使用rmic命令生成存根
RemoteConcreteSubject_Stub.class