Java網路程式設計的基本網路概念
前言
自己網路這方面的知識很是薄弱,每次面試被問到這部分都會卡殼,所以很尷尬,然後最近也是有些時間了,就趕緊把自己的不足補充一下。雖然最近也在看設計模式,但是總看設計模式也容易煩,所以就並行學習,看看設計模式,然後再看看這網路程式設計。
網路
首先熟悉一下, 什麼是網路,網路是幾乎可以實時相互發送和接收資料的計算機和其他裝置的集合。網路通常用線纜連線,資料為轉換為電磁波,通過線纜移動。不過,無線網路會通過無線電波傳輸資料,許多長距離的傳輸現在會用通過玻璃纖維傳送可見光的光纖電纜來完成。
網路中的每臺機器為一個節點(node)。大多數節點是計算機,但是印表機、路由器、網橋、閘道器、ATM機也都是節點。每個網路節點都有地址 (address),這是用於唯一標識節點的一個位元組序列。每個地址中的位元組越多,可用的地址就越多,就可以有更多的裝置同時連入網路。
不同的網路會以不同的方式分配地址。乙太網(Ethernet)地址與物理乙太網硬體關聯。乙太網硬體的生產廠家使用預分配的廠商編碼確保他們的硬體地址或與其他廠家的硬體地址不衝突。每家廠商都要負責保證不會生產出兩塊地址相同的乙太網卡。
所有現代計算機網路都是包交換(分組交換)網路:流經網路的資料分割成小塊,稱為包(packet,也稱分組),每個包都單獨加以處理。每個包都包含了由誰傳送和將發往何處的資訊。
計算機來回傳遞資料時還有另一個重要的一個點,那就是協議,協議(protocol)是定義計算機如何通訊的一組明確的規則:包括地址格式、資料如何分包等。針對網路通訊的不同方面,定義有很多不同的協議。例如:Hypertext Transfer Protocol(HTTP)。
網路分層
通過網路傳送資料是一項複雜的操作,必須仔細地協調網路的物理特性以及所傳送資料的路基特徵。為了對應用程式開發人員和終端使用者隱藏這種複雜性,網路通訊的不同方面被分解為多個層。每一層表示為物理硬體(即線纜和電流)與所傳輸資訊之間的不同抽象層次。在理論上,每一層只與緊挨其上和其下的層對話。將網路分層,這樣就可以修改甚至替換某一層的軟體,只要層與層之間的介面保持不變,就不會影響到其他層。
上面的圖顯示了網路中可能存在的協議棧。
有幾種不同的分層模型,分別適合特定型別網路的需要。我這邊主要介紹適用於Internet的標準TCP/IP四層模型,如下圖所示:
主機網路層
主機網路層定義了一個特定的網路介面(如乙太網或WiFi天線)如何通過物理連線向本地網路或世界其他地方傳送IP資料報。主機網路層中,由連線不同計算機的硬體(線纜、光纖電纜、無線電波或煙訊號)組成的部分有時稱為網路的物理層。Java程式設計師不需要擔心這一層,除非出現了問題,比如插頭從計算機後面掉了下來,或者有人挖斷了你與外部世界之間的T-1線。換句話說,Java從來都看不到物理層。
網際層
網際層主機網路層的下一層,這也是作為Java程式設計師需要考慮的第一層,網際層協議定義了資料位和位元組如何組織為更大的分組,稱為包,還定義了定址機制,不同計算機要按這個定址機制查詢對方。網際協議(IP)是世界上使用最廣泛的網際層協議,也是Java唯一理解的網際層協議。
網際協議主要是兩個協議:IPV4和IPV6,IPV4使用32位地址,IPV6使用128位地址,另外還增加了一些技術特性來幫助完成路由。這是兩個完全不同的網路協議,如果沒有特殊的閘道器/或隧道協議,即使在相同的網路上它們也無法做到互操作,不過Java幾乎對你隱藏了所有這些區別。
除了路由和定址,網際層的第二個作用是支援不同型別的主機網路層相互對話。Internet路由器會完成WiFi和Ethernet、Ethernet和DSL、DSL和光纖往返等協議之間的轉換。如果沒有網際層或類似的分層,則每個計算機只能與同一類網路上的其他計算機對話。網際層負責使用同夠協議將異構網路相互連線。
傳輸層
原始資料報有一些缺點。最顯著的缺點是不能保證可靠傳送,即使能傳送也可能在傳輸中遭到破壞。首部校驗只能檢測首部中的破壞情況,而不能檢測資料報中的資料部分。最後即使資料報能到底目的地而未被破壞,也不一定會以傳送時的順序到達。
傳輸層(transport layer)負責確保各包以傳送的順序接收,並保證沒有資料丟失或破壞。如果丟包,傳輸層會請求傳送方重傳這個包。為實現這個目標,IP網路會給每個資料報新增一個附加首部,其中包含有更多資訊。
這一層上主要有兩個協議。第一個是傳輸控制協議(Transmission Control Protocol,TCP),這是一個開銷很高的協議,支援對丟失或破壞的資料進行重傳,並按照發送時的順序進行傳送。第二個協議是使用者資料報協議(User Datagram Protocol ,UDP),它允許接收方檢測被破壞的包,但不保證這些包以正確的順序傳送(或者包有可能根本未傳送)。但是,UDP通常比TCP快。TCP稱為可靠(reliable)協議;UDP是不可靠(unreliable)協議。
應用層
向用戶傳送資料的層稱為應用層(application layer)。它下面的三層共同定義了資料如何從一臺計算機傳輸到另一臺計算機。應用層確定了資料傳輸後的操作。有使用者Web的HTTP,還有使用者電子郵件的SMTP、POP、IMAP、;用於檔案傳輸的FTP、FSP、TFTP,用於檔案訪問的NFS;用於檔案共享的Gnutella和BitTorrent;用於語音通訊的會話啟動協議(Session Initiation Protocol,SIP)和Skype等。此外你的程式可以在必要時定義自己的應用層協議。
IP、TCP、UDP
IP設計為允許任意兩點之間有多個路由,可以繞過被破壞的路由器實現資料包的路由。由於兩點間存在多個路由,並且兩點間的最短路徑可能由於網路業務流量或其他因素而隨時間改變,所以構成某個特定資料流的包可能不會採用相同的路由。另外,即使它們全部到達,也可能不會以傳送的順序到達。為了改進這種基本機制,將TCP置於IP之上,使連線的兩端能夠確認接收IP包,以及請求重傳丟失或被破壞的包。此外,TCP允許接收端的包按傳送時的順序重新組合在一起。
不過,TCP會有很大的開銷。因此,如果有些情況丟失個別包不會完全破壞資料的話,也可以使用UDP傳送資料包,而不需要TCP提供保證。UDP是不可靠協議,它不能保證包一定會到達目的地,也不保證包會以傳送時的相同順序到達。但是它開銷小,速度快,也可以在應用層的UDP資料流中建立糾錯碼,來解決資料丟失問題。
可以在IP之上執行很多其他協議。但是Java支援的協議只有TCP和UDP,以及建立在TCP和UDP之上的應用層協議。所有其他傳輸層、網際層和更底層的協議,如ICMP、IGMP、ARP、RARP、RSVP和其他洗衣在Java程式中都只能通過連線到原生程式碼來實現。
IP地址和域名
IPv4網路中的每臺計算機都有一個4位元組的數字標識。一般寫為點分四段格式,如192.1.32.90,這4個數中,每個數都是一個無符號位元組,範圍從0到255。IPv4網路中的每臺計算機都有一個唯一的4節地址。當資料通過網路傳輸時,包的首部會包括要發往的機器地址(目的地址)和傳送這個包的機器地址(源地址)。沿路的路由器通過檢查目的地址來選擇傳送資料包的最佳路由。包括源地址是為了讓接收方知道要向誰回覆。
雖然計算機可以輕鬆地處理數字,但人類對於記憶數字卻不在行。因此開發了域名系統(Domain Name System,DNS)用來將人類易於記憶的主機名(如www.12345.com)轉換為數字Internet地址(如208.201.243.99)。當Java程式訪問網路時,他們需要同時處理數字地址和相應的主機名。這些方法由java.net.InetAddress類提供。
埠
如果每臺計算機一次只做一件事情,那麼地址可能就足夠了。但是,現代計算機同時要做很多不同的事情。電子郵件需要與FTP請求分開,而FTP又要與Web業務流分開。這是通過埠(port)實現的。每臺有IP地址的計算機都有幾千個邏輯埠(確切地講,每個傳輸層協議有65535個埠)。這些只是計算機記憶體中的抽象,不表示任何物理實物,與USB埠不同。每個埠由1到65535之間的一個數字標識。每個埠可以分配給一個特定的服務。
防火牆
Internet上有些頑皮的人。為了把他們關在門外,在本地網路建立一個訪問點,檢查所有進出該訪問點的業務流通常很有用。位於Internet和本地網路之間的一些硬體和軟體會檢查所有進出的資料,以保證其合法性,這就稱為防火牆(firewall)。防火牆通常是將本地網路連線到更大的Internet的路由器的一部分,還可以完成其他任務,如網路地址轉換。此外,防火牆也可以是單獨的機器。防火牆主要還是負責檢查傳入或傳出其網路介面的各個包,根據一組規則接收或拒絕這些包。
過濾通常是基於網路地址和埠的。Java與防火牆沒有太大關係,除非防火牆總是礙你事。