1 網絡編程概述
Java是 Internet 上的語言,它從語言級上提供了對網絡應用程序的支持,程序員能夠很容易開發常見的網絡應用程序。
Java提供的網絡類庫,可以實現無痛的網絡連接,聯網的底層細節被隱藏在 Java 的本機安裝系統裏,由 JVM 進行控制。並且 Java 實現了一個跨平臺的網絡庫,程序員面對的是一個統一的網絡編程環境。
計算機網絡:
把分佈在不同地理區域的計算機與專門的外部設備用通信線路互連成一個規模大、功能強的網絡系統,從而使衆多的計算機可以方便地互相傳遞信息、共享硬件、軟件、數據信息等資源。
網絡編程的目的:
直接或間接地通過網絡協議與其它計算機進行通訊。
網絡編程中有兩個主要的問題:
Ø如何準確地定位網絡上一臺或多臺主機
Ø找到主機後如何可靠高效地進行數據傳輸
2 通訊要素
2.1 網絡通信要素
l如何實現網絡中的主機互相通信:
Ø通信雙方地址
Ø一定的規則(有兩套參考模型)
OSI參考模型:模型過於理想化,未能在因特網上進行廣泛推廣
TCP/IP參考模型(或TCP/IP協議):事實上的國際標準。
2.2 網絡通信協議
3 InetAddress類
3.1 IP 和 端口號
lIP 地址:InetAddress
Ø唯一的標識 Internet 上的計算機
Ø本地迴環地址(hostAddress):127.0.0.1 主機名(hostName):localhost
Ø不易記憶
端口號標識正在計算機上運行的進程(程序)
Ø不同的進程有不同的端口號
Ø被規定爲一個 16 位的整數 0~65535。其中,0~1023被預先定義的服務通信佔用(如http佔用端口80,Tomcat佔用端口8080,MySql佔用端口3306,Oracle佔用端口1521等)。除非我們需要訪問這些特定服務,否則,就應該使用 1024~65535 這些端口中的某一個進行通信,以免發生端口衝突。
l端口號與IP地址的組合得出一個網絡套接字:Socket。
3.2 InetAddress類
lInternet上的主機有兩種方式表示地址:
Ø域名(hostName):www.atguigu.com
ØIP 地址(hostAddress):202.108.35.210
lInetAddress類主要表示IP地址,兩個子類:Inet4Address、Inet6Address。
lInetAddress 類對象含有一個 Internet 主機地址的域名和IP地址:www.atguigu.com 和 202.108.35.210。
l域名容易記憶,當在連接網絡時輸入一個主機的域名後,域名服務器(DNS)負責將域名轉化成IP地址,這樣才能和主機建立連接。 -------域名解析
InetAddress address1 = InetAddress.getByName("www.baidu.com");
System.out.println(address1);
System.out.println(address1.getHostName());//獲得對象所含域名
System.out.println(address1.getHostAddress());//對象所含IP地址
InetAddress address2 = InetAddress.getLocalHost();//本機域名和IP地址
System.out.println(address2);
4 TCP網絡通信
網絡通信協議
計算機網絡中實現通信必須有一些約定,即通信協議,對速率、傳輸代碼、代碼結構、傳輸控制步驟、出錯控制等制定標準。
通信協議分層的思想
由於結點之間聯繫很複雜,在制定協議時,把複雜成份分解成一些簡單的成份,再將它們復合起來。最常用的複合方式是層次方式,即同層間可以通信、上一層可以調用下一層,而與再下一層不發生關係。各層互不影響,利於系統的開發和擴展。
4.1 TCP/IP協議簇
傳輸層協議中有兩個非常重要的協議:
Ø傳輸控制協議TCP(Transmission Control Protocol)
Ø用戶數據報協議UDP(User Datagram Protocol)。
TCP/IP 以其兩個主要協議:傳輸控制協議(TCP)和網絡互聯協議(IP)而得名,實際上是一組協議,包括多個具有不同功能且互爲關聯的協議。
IP(Internet Protocol)協議是網絡層的主要協議,支持網間互連的數據通信。
lTCP/IP協議模型從更實用的角度出發,形成了高效的四層體系結構,即物理鏈路層、IP層、傳輸層和應用層。
4.2 TCP 和 UDP
TCP協議:
Ø使用TCP協議前,須先建立TCP連接,形成傳輸數據通道
Ø傳輸前,採用“三次握手”方式,是可靠的
ØTCP協議進行通信的兩個應用進程:客戶端、服務端
Ø在連接中可進行大數據量的傳輸
Ø傳輸完畢,需釋放已建立的連接,效率低
UDP協議:
Ø將數據、源、目的封裝成數據包,不需要建立連接
Ø每個數據報的大小限制在64K內
Ø因無需連接,故是不可靠的
Ø發送數據結束時無需釋放資源,速度快
4.3 Socket
利用套接字(Socket)開發網絡應用程序早已被廣泛的採用,以至於成爲事實上的標準。
通信的兩端都要有Socket,是兩臺機器間通信的端點
網絡通信其實就是Socket間的通信。
Socket允許程序把網絡連接當成一個流,數據在兩個Socket間通過IO傳輸。
一般主動發起通信的應用程序屬客戶端,等待通信請求的爲服務端。
Java語言的基於套接字編程分爲服務端編程和客戶端編程,其通信模型如圖所示:
Socket類的常用方法
方法 |
功能 |
InetAddress getLocalAddress() |
返回對方Socket中的IP的InetAddress對象 |
int getLocalPort() |
返回本地Socket中的端口號 |
InetAddress getInetAddress() |
返回對方Socket中IP地址 |
int getPort() |
返回對方Socket中的端口號 |
void close() throws IOException |
關閉Socket,不可在以後的網絡連接中使用,除非創建新的套接字 |
InputStream getInputStream() throws Exception |
獲取與Socket相關聯的字節輸入流,用於從Socket中讀數據。 |
OutputStream getOutputStream() throws IOException |
獲取與Socket相關聯的字節輸出流,用於向Socket中寫數據。 |
ServerSocket類的常用方法
方 法 |
功 能 |
Socket accept() throws IOException |
等待客戶端的連接請求,返回與該客戶端進行通信用的Socket對象 |
void setSoTimeout(int timeout) throws SocketException |
設置accept()方法等待連接的時間爲timeout毫秒。若時間已到,還沒有客戶端連接,則拋出InterruptedIOException異常,accept()方法不再阻塞,該傾聽Socket可繼續使用。若timeout值爲0,則表示accept()永遠等待。該方法必須在傾聽Socket創建後,在accept()之前調用纔有效。 |
void close()throws IOException |
關閉監聽Socket |
InetAddress getInetAddress() |
返回此服務器套接字的本地地址 |
int getLocalPort() |
返回此套接字在其上監聽的端口號 |
SocketAddress getLocalSocketAddress() |
返回此套接字綁定的端點的地址 |
客戶端Socket的工作過程包含以下四個基本的步驟:
Ø創建 Socket:根據指定服務端的 IP 地址或端口號構造 Socket 類對象。若服務器端響應,則建立客戶端到服務器的通信線路。若連接失敗,會出現異常。
Ø打開連接到 Socket 的輸入/出流: 使用 getInputStream()方法獲得輸入流,使用 getOutputStream()方法獲得輸出流,進行數據傳輸
Ø按照一定的協議對 Socket 進行讀/寫操作:通過輸入流讀取服務器放入線路的信息(但不能讀取自己放入線路的信息),通過輸出流將信息寫入線程。
Ø關閉 Socket:斷開客戶端到服務器的連接,釋放線路
客戶端創建Socket對象
客戶端程序可以使用Socket類創建對象,創建的同時會自動向服務器方發起連接。Socket的構造方法是:
ØSocket(String host,int port)throws UnknownHostException,IOException:向服務器(域名是host。端口號爲port)發起TCP連接,若成功,則創建Socket對象,否則拋出異常。
ØSocket(InetAddress address,int port)throws IOException:根據InetAddress對象所表示的IP地址以及端口號port發起連接。
客戶端建立socketAtClient對象的過程就是向服務器發出套接字連接請求
Socket s = new Socket(“192.168.40.165”,9999);
OutputStream out = s.getOutputStream();
out.write(“hello”.getBytes());
s.close();
服務器程序的工作過程包含以下四個基本的步驟:
Ø調用 ServerSocket(int port) :創建一個服務器端套接字,並綁定到指定端口上。用於監聽客戶端的請求。
Ø調用 accept():監聽連接請求,如果客戶端請求連接,則接受連接,返回通信套接字對象。
Ø調用 該Socket類對象的 getOutputStream() 和 getInputStream ():獲取輸出流和輸入流,開始網絡數據的發送和接收。
Ø關閉ServerSocket和Socket對象:客戶端訪問結束,關閉通信套接字。
ServerSocket 對象負責等待客戶端請求建立套接字連接,類似郵局某個窗口中的業務員。也就是說,服務器必須事先建立一個等待客戶請求建立套接字連接的ServerSocket對象。
所謂“接收”客戶的套接字請求,就是accept()方法會返回一個 Socket 對象。
ServerSocket ss = new ServerSocket(9999);
Socket s = ss.accept ();
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int num = in.read(buf);
String str = new String(buf,0,num);
System.out.println(s.getInetAddress().toString()+”:”+str);
s.close();
ss.close();
5 UDP網絡通信
類 DatagramSocket 和 DatagramPacket 實現了基於 UDP 協議網絡程序。
UDP數據報通過數據報套接字 DatagramSocket 發送和接收,系統不保證UDP數據報一定能夠安全送到目的地,也不能確定什麼時候可以抵達。
DatagramPacket 對象封裝了UDP數據報,在數據報中包含了發送端的IP地址和端口號以及接收端的IP地址和端口號。
UDP協議中每個數據報都給出了完整的地址信息,因此無須建立發送方和接收方的連接。
流 程:
1.DatagramSocket與DatagramPacket
2.建立發送端,接收端
3.建立數據包
4.調用Socket的發送、接收方法
5.關閉Socket
發送端與接收端是兩個獨立的運行程序。
//發送端
DatagramSocket ds = new DatagramSocket();
byte[] by = “hello,atguigu.com”.getBytes();
DatagramPacket dp = new DatagramPacket(by,0,by.length,
InetAddress.getByName(“127.0.0.1”),10000);
ds.send(dp);
ds.close();
//接收端
//要指定監聽的端口
DatagramSocket ds = new DatagramSocket(10000);
byte[] by = new byte[1024];
DatagramPacket dp = new DatagramPacket(by,by.length);
ds.receive(dp);
String str = new String(dp.getData(),0,dp.getLength());
System.out.println(str+"--"+dp.getAddress());
ds.close();
6 URL編程
URL(Uniform Resource Locator):統一資源定位符,它表示 Internet 上某一資源的地址。通過 URL 我們可以訪問 Internet 上的各種網絡資源,比如最常見的 www,ftp 站點。瀏覽器通過解析給定的 URL 可以在網絡上查找相應的文件或其他資源。
URL的基本結構由5部分組成:
Ø<傳輸協議>://<主機名>:<端口號>/<文件名>
Ø例如: http://192.168.1.100:8080/helloworld/index.jsp
Øhttp://127.0.0.1:8080/examples/hello.txt
爲了表示URL,java.net 中實現了類 URL。我們可以通過下面的構造器來初始化一個 URL 對象:
Øpublic URL (String spec):通過一個表示URL地址的字符串可以構造一個URL對象。例如:URL url = new URL ("http://www. yizhihanduxiu.com/");
Øpublic URL(URL context, String spec):通過基 URL 和相對 URL 構造一個 URL 對象。例如:URL downloadUrl = new URL(url, “download.html")
Øpublic URL(String protocol, String host, String file); 例如:new URL("http", "www.yizhihanduxiu.com", “download. html");
Øpublic URL(String protocol, String host, int port, String file); 例如: URL gamelan = new URL("http", "www.yizhihanduxiu.com", 80, “download.html");
類URL的構造方法都聲明拋出非運行時異常,必須要對這一異常進行處理,通常是用 try-catch 語句進行捕獲。
一個URL對象生成後,其屬性是不能被改變的,但可以通過它給定的方法來獲取這些屬性:
Øpublic String getProtocol( ) 獲取該URL的協議名
Øpublic String getHost( ) 獲取該URL的主機名
Øpublic String getPort( ) 獲取該URL的端口號
Øpublic String getPath( ) 獲取該URL的文件路徑
Øpublic String getFile( ) 獲取該URL的文件名
Øpublic String getQuery( ) 獲取該URL的查詢名
URL url = new URL("http://localhost:8080/examples/myTest.txt");
System.out.println("getProtocol() :"+url.getProtocol());
System.out.println("getHost() :"+url.getHost());
System.out.println("getPort() :"+url.getPort());
System.out.println("getPath() :"+url.getPath());
System.out.println("getFile() :"+url.getFile());
System.out.println("getQuery() :"+url.getQuery());
URL的方法 openStream():能從網絡上讀取數據
若希望輸出數據,例如向服務器端的 CGI (公共網關接口-Common Gateway Interface-的簡稱,是用戶瀏覽器和服務器端的應用程序進行連接的接口)程序發送一些數據,則必須先與URL建立連接,然後才能對其進行讀寫,此時需要使用 URLConnection
URLConnection:表示到URL所引用的遠程對象的連接。當與一個URL建立連接時,首先要在一個 URL 對象上通過方法 openConnection() 生成對應的 URLConnection 對象。如果連接過程失敗,將產生IOException.
ØURL netchinaren = new URL ("http://www.atguigu.com/index.shtml");
ØURLConnectonn u = netchinaren.openConnection( );
通過URLConnection對象獲取的輸入流和輸出流,即可以與現有的CGI程序進行交互。
Øpublic Object getContent( ) throws IOException
Øpublic int getContentLength( )
Øpublic String getContentType( )
Øpublic long getDate( )
Øpublic long getLastModified( )
Øpublic InputStream getInputStream( )throws IOException
Øpublic OutputSteram getOutputStream( )throws IOException
7 小結
位於網絡中的計算機具有唯一的IP地址,這樣不同的主機可以互相區分。
客戶端-服務器是一種最常見的網絡應用程序模型。服務器是一個爲其客戶端提供某種特定服務的硬件或軟件。客戶機是一個用戶應用程序,用於訪問某臺服務器提供的服務。端口號是對一個服務的訪問場所,它用於區分同一物理計算機上的多個服務。套接字用於連接客戶端和服務器,客戶端和服務器之間的每個通信會話使用一個不同的套接字。TCP協議用於實現面向連接的會話。
Java 中有關網絡方面的功能都定義在 java.net 程序包中。Java 用 InetAddress 對象表示 IP 地址,該對象裏有兩個字段:主機名(String) 和 IP 地址(int)。
類 Socket 和 ServerSocket 實現了基於TCP協議的客戶端-服務器程序。Socket是客戶端和服務器之間的一個連接,連接創建的細節被隱藏了。這個連接提供了一個安全的數據傳輸通道,這是因爲 TCP 協議可以解決數據在傳送過程中的丟失、損壞、重複、亂序以及網絡擁擠等問題,它保證數據可靠的傳送。
類 URL 和 URLConnection 提供了最高級網絡應用。URL 的網絡資源的位置來同一表示 Internet 上各種網絡資源。通過URL對象可以創建當前應用程序和 URL 表示的網絡資源之間的連接,這樣當前程序就可以讀取網絡資源數據,或者把自己的數據傳送到網絡上去。