文章目錄
- 1.OSI與TCP/IP體系模型
- 2.IP和連接埠
-
- 3.TCP和UDP協議
- 4.Socket
- 5.常用應用程式層協議
- 1.InteAddress類
- 2.URL和URLConnection類
- 3.URLDecoder和URLEncoder
- 4.Socket和ServerSocket類
- 5.DatagramSocket類
一、網路編程基本概念1.OSI與TCP/IP體系模型
2.IP和連接埠
解決了文章最開始提到的定位的問題。
IP在互連網中能唯一標識一台電腦,是每一台電腦的唯一標識(身份證);網路編程是和遠端電腦的通訊,所以必須先能定位到遠端電腦;IP協助解決此問題;一台電腦中可能有很多進程,具體和哪一個進程進行通訊,這就得靠連接埠來識別;
IP和連接埠能唯一定位到需要通訊的進程。這裡的IP表示地址,區別於IP協議。在OSI體系還是TCP/IP體系中,IP協議位於網際層,來封裝IP地址到報文中。
3.TCP和UDP協議
TCP是Tranfer Control Protocol的簡稱,是一種連線導向的保證可靠傳輸的協議。通過TCP協議傳輸,得到的是一個順序的無差錯的資料流。發送方和接收方的成對的兩個socket之間必須建立串連,以便在TCP協議的基礎上進行通訊,當一個socket(通常都是server socket)等待建立串連時,另一個socket可以要求進行串連,一旦這兩個socket串連起來,它們就可以進行雙向資料轉送,雙方都可以進行發送或接收操作。
UDP是User Datagram Protocol的簡稱,是一種不需連線的協議,每個資料報都是一個獨立的資訊,包括完整的源地址或目的地址,它在網路上以任何可能的路徑傳往目的地,因此能否到達目的地,到達目的地的時間以及內容的正確性都是不能被保證的。
比較:
UDP:
- 每個資料報中都給出了完整的地址資訊,因此無需要建立發送方和接收方的串連。
- UDP傳輸資料時是有大小限制的,每個被傳輸的資料報必須限定在64KB之內。
- UDP是一個不可靠的協議,發送方所發送的資料報並不一定以相同的次序到達接收方
TCP:
- 連線導向的協議,在socket之間進行資料轉送之前必然要建立串連,所以在TCP中需要連線時間。
- TCP傳輸資料大小限制,一旦串連建立起來,雙方的socket就可以按統一的格式傳輸大的資料。
- TCP是一個可靠的協議,它確保接收方完全正確地擷取發送方所發送的全部資料。
資料楨:
應用:
- TCP在網路通訊上有極強的生命力,例如遠端連線(Telnet)和檔案傳輸(FTP)都需要不定長度的資料被可靠地傳輸。但是可靠的傳輸是要付出代價的,對資料內容正確性的檢驗必然佔用電腦的處理時間和網路的頻寬,因此TCP傳輸的效率不如UDP高。
- UDP操作簡單,而且僅需要較少的監護,因此通常用於區域網路高可靠性的分散系統中client/server應用程式。例如視頻會議系統,並不要求音頻視頻資料絕對的正確,只要保證連貫性就可以了,這種情況下顯然使用UDP會更合理一些。
4.Socket
Socket是網路驅動層提供給API和一種機制。我們可以把 Socket 比喻成是一個港口碼頭。應用程式只要把貨物放到港口碼頭上,就算完成了貨物的運送。對於接收方應用程式也要建立一個港口碼頭,只需要等待貨物到達碼頭後將貨物取走。
Socket 是在應用程式中建立的,它是通過一種綁定機制與驅動程式建立關係,告訴自己所對應的 IP 和 Port。在網路上傳輸的每一個資料幀,必須包含寄件者的 IP 位址和連接埠號碼。建立完 Socket 以後,應用程式寫入到 Socket 的資料,由 Socket 交給驅動程式向網路上發送資料,電腦從網路上收到與某個 Socket 綁定的 IP 和 Port 相關的資料後,由驅動程式再交給 Socket ,應用程式就可以從這個 Socket 中讀取接收到的資料。網路應用程式就是這樣通過 Socket 發送和接收的。
Socket資料發送過程:
Socket資料接收過程:
5.常用應用程式層協議應用程式層協議是為瞭解決某一類應用問題,而問題的解決又往往是通過位於不同主機中的多個應用進程之間的通訊和協同工作來完成的。應用程式層的具體內容就是規定應用進程在通訊時所遵循的協議。
二、Java網路編程常用類1.InteAddress類
Java中的InetAddress是一個代表IP地址的封裝。IP地址可以由位元組數組和字串來分別表示,InetAddress將IP地址以對象的形式進行封裝,可以更方便的操作和擷取其屬性。InetAddress沒有構造方法,可以通過兩個靜態方法獲得它的對象。
//根據主機名稱來擷取對應的InetAddress執行個體
InetAddress ip = InetAddress.getByName("www.baidu.com");
//判斷是否可達
System.out.println("baidu是否可達:" + ip.isReachable(2000));
//擷取該InetAddress執行個體的IP字串
System.out.println(ip.getHostAddress());
//根據原始IP地址(位元組數組形式)來擷取對應的InetAddress執行個體
InetAddress local = InetAddress.getByAddress(new byte[]{127,0,0,1});
System.out.println("本機是否可達:" + local.isReachable(5000));
//擷取該InetAddress執行個體對應的全限定網域名稱
System.out.println(local.getCanonicalHostName());
2.URL和URLConnection類
網路中的URL(Uniform Resource Locator)是統一資源定位器的簡稱。它表示Internet上某一資源的地址。通過URL我們可以訪問Internet上的各種網路資源,比如最常見的WWW,FTP網站。 URL可以被認為是指向互連網資源的“指標”,通過URL可以獲得互連網資源相關資訊,包括獲得URL的InputStream對象擷取資源的資訊,以及一個到URL所引用遠程對象的串連URLConnection。 URLConnection對象可以向所代表的URL發送請求和讀取URL的資源。通常,建立一個和URL的串連,需要如下幾個步驟:
- 建立URL對象,並通過調用openConnection方法獲得URLConnection對象;
- 設定URLConnection參數和普通請求屬性;
- 向遠端資源發送請求;
- 遠端資源變為可用,程式可以訪問遠端資源的頭欄位和通過輸入資料流來讀取遠端資源返回的資訊。
這裡需要重點討論一下第三步:如果只是發送GET方式請求,使用connect方法建立和遠端資源的串連即可;如果是需要發送POST方式的請求,則需要擷取URLConnection對象所對應的輸出資料流來發送請求。這裡需要注意的是,由於GET方法的參數傳遞方式是將參數顯式追加在地址後面,那麼在構造URL對象時的參數就應當是包含了參數的完整URL地址,而在獲得了URLConnection對象之後,就直接調用connect方法即可發送請求。而POST方法傳遞參數時僅僅需要頁面URL,而參數通過需要通過輸出資料流來傳遞。另外還需要設定頭欄位。以下是兩種方式的代碼:
//1. 向指定URL發送GET方法的請求
String urlName = url + "?" + param;
URL realUrl = new URL(urlName);
//開啟和URL之間的串連
URLConnection conn = realUrl.openConnection();
//設定通用的請求屬性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
//建立實際的串連
conn.connect();
//2. 向指定URL發送POST方法的請求
URL realUrl = new URL(url);
//開啟和URL之間的串連
URLConnection conn = realUrl.openConnection();
//設定通用的請求屬性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
//發送POST請求必須設定如下兩行
conn.setDoOutput(true);
conn.setDoInput(true);
//擷取URLConnection對象對應的輸出資料流
out = new PrintWriter(conn.getOutputStream());
//發送請求參數
out.print(param);
3.URLDecoder和URLEncoder
這兩個類可以別用於將application/x-www-form-urlencoded MIME類型的字串轉換為一般字元串,將一般字元串轉換為這類特殊型的字串。使用URLDecoder類的靜態方法decode()用於解碼,URLEncoder類的靜態方法encode()用於編碼。具體使用方法如下:
//將application/x-www-form-urlencoded字串轉換成一般字元串
String keyWord = URLDecoder.decode("%E6%9D%8E%E5%88%9A+j2ee", "UTF-8");
System.out.println(keyWord);
//將一般字元串轉換成 application/x-www-form-urlencoded字串
String urlStr = URLEncoder.encode( "ROR敏捷開發最佳指南" , "GBK");
System.out.println(urlStr);
4.Socket和ServerSocket類
網路上的兩個程式通過一個雙向的通訊串連實現資料的交換,這個雙向鏈路的一端稱為一個Socket。Socket通常用來實現客戶方和服務方的串連。Socket是TCP/IP協議的一個十分流行的編程介面,一個Socket由一個IP地址和一個連接埠號碼唯一確定。 但是,Socket所支援的協議種類也不光TCP/IP一種,因此兩者之間是沒有必然聯絡的。在Java環境下,Socket編程主要是指基於TCP/IP協議的網路編程。 Server端Listen(監聽)某個連接埠是否有串連請求,Client端向Server端發出Connect(串連)請求,Server端向Client端發回Accept(接受)訊息。一個串連就建立起來了。Server端和Client端都可以通過Send,Write等方法與對方通訊。 TCP Socket的通訊過程如:
5.DatagramSocket類
UDP協議是一種不可靠的網路通訊協定,它在通訊執行個體的兩端個建立一個Socket,但這兩個Socket之間並沒有虛擬連結,這兩個Socket只是發送和接受資料報的對象。 包java.net中提供了兩個類DatagramSocket和DatagramPacket用來支援資料報通訊,DatagramSocket用於在程式之間建立傳送資料報的通訊串連, DatagramPacket則用來表示一個資料報。 DatagramSocket的構造方法:
DatagramSocket();
DatagramSocket(int prot);
DatagramSocket(int port, InetAddress laddr);
其中,port指明socket所使用的連接埠號碼,如果未指明連接埠號碼,則把socket串連到本地主機上一個可用的連接埠。laddr指明一個可用的本地地址。給出連接埠號碼時要保證不發生連接埠衝突,否則會產生SocketException類例外。注意:上述的兩個構造方法都聲明拋棄非運行時例外SocketException,程式中必須進行處理,或者捕獲、或者聲明拋棄。 用資料報方式編寫client/server程式時,無論在客戶方還是服務方,首先都要建立一個DatagramSocket對象,用來接收或發送資料報,然後使用DatagramPacket類對象作為傳輸資料的載體。
三、總結
- 網路編程的核心是IP、連接埠、協議三大元素
- 網路編程的本質是處理序間通訊
- 網路編程的2個主要問題:1是定位主機,2是資料轉送
參考資料:
http://blog.csdn.net/driverking/article/details/6573992 http://blog.sina.com.cn/s/blog_6213b4e50100je4g.html http://52android.blog.51cto.com/2554429/482954 http://hi.baidu.com/refresh/blog/item/1ab994dd4f6957315982ddaa.html