聯網的各個終端之間能否進行交互的軟件基礎是網絡協議棧,目前主流的網絡協議棧是TCP/IP協議棧。
1、主機到網絡層協議:以太網協議
主機到網絡層主要為IP協議和ARP協議提供服務、發送和接收網絡數據報。本層中由於要實現跨網和跨設備的互通,有很多的實現方式,這里我們只關注以太網的實現方式。
以太網是由數字設備公司(Digital Equipment Corp,DEC)、英特爾公司和Xerox公司在1982年公布的一個標准。目前TCP/IP技術主要基於以太網標准。以太網標准采用一種帶沖突檢測的載波監聽多路接入(CSMA/CD,Carrier Sense,Multiple Access with Collision Detection)的方法進行傳輸。以太網的封包格式如下圖所示,它在IP數據的基礎上增加了共14個字節。
源地址和目的地址:以太網用48bits(6字節)來表示源地址和目的地址。這里的源地址和目的地址指的是硬件地址,例如網卡的MAC地址。
在地址后面是兩個字節的表示類型的字段,例如0800表示此幀數據為IP數據,0806表示此幀數據為ARP請求。
類型字段之后是數據,對於以太網,規定數據段的大小范圍是46-1500個字節,如果數據不足46個字節,則要用空字符填滿。
注意:數據段的長度有一個最大值,以太網為1500,這個特性稱為MTU,即最大傳輸單元。如果IP層有一個要求傳送的數據長度比MTU大,那么在IP層要對數據進行分片,使得每個片都小於MTU。
CRC字段用於對幀內數據進行校驗,以保證數據的正確性,通常由硬件實現(例如在網卡設備中實現)。
注意:以太網的頭部長度為14的特點在某些平台的實現上會造成效率上的問題,例如4字節對齊的平台,在取得IP數據時通常會重新復制一次。
2、IP協議
IP協議是TCP/IP協議中最重要的協議,它為TCP、UDP、ICMP等協議提供傳輸的通路。IP層的主要目的是提供子網的互聯,形成較大的網絡,使不同的子網間能夠傳輸數據。IP層主要有如下作用:
IP數據的格式如下圖所示,不包含選項字段,其頭部長度為20字節。
源IP地址和目的IP地址:源地址表示發送數據的主機或設備的IP地址,目的地址表示接收數據的主機IP地址。這兩個字段均為32位。本字段的目的在於識別Internet上的主機。
3、網際控制報文協議(ICMP)
ICMP協議用於傳遞差錯信息、時間、回顯、網絡信息等報文控制數據。
ICMP協議的數據位於IP字段的數據部分,它是在IP報文的內部被傳送的。
ICMP報文的數據格式如下圖所示:
ICMP的報文類型由類型和代碼兩個字段共同決定。
4、傳輸控制協議(TCP)
傳輸控制協議(Transmission Control Protocol),簡稱TCP協議,它在原有IP協議的基礎上,增加了確認重發、滑動窗口和復用/解復用等機制,提供一種可靠的、面向連接的、字節流服務。
首先,TCP提供客戶和服務器的連接。
其次,TCP提供可靠性。(數據的可靠投遞或故障的可靠通知)並不能保證數據一定會被對方端點接收。
第三,TCP通過給所發送數據的每一個字節關聯一個序列號進行排序(sequencing)。
第四,TCP提供流量控制(flow control)。TCP總是告訴對端它能夠接收多少字節的數據,這稱為通告窗口(advertised window)。該窗口在任何時刻都指出接收緩沖區中的可用空間,從而確保發送端發送的數據不會溢出接收緩沖區。該窗口時時刻刻動態地變化着:當接收來自發送端的數據時,窗口大小減小;而當接收端應用進程從緩沖區中讀取數據時,窗口大小增大。
最后,TCP的連接是全雙工的(full duplex)。
TCP的特點:
TCP的數據格式:
源端口號和目的端口號:這兩個字段均為16位的長度,表示發送端和接收端的端口,用於確認發送端和接收端的應用程序。發送端的IP地址和端口號以及接收端的IP地址和端口號可以確認一個在Internet上的TCP連接。
TCP的封裝解封過程:
建立TCP連接的三次握手:
(1)服務器必須准備好接受外來的連接。這通過調用socket、bind和listen函數來完成,稱為被動打開(passive open)。
(2)客戶通過調用connect進行主動打開(active open)。這引起客戶TCP發送一個SYN(表示 同步)分節(segment),它告訴服務器客戶將在(待建立的)連接中發送數據的初始序列號。一般情況下SYN分節不攜帶數據,它只含一個IP頭部、一個TCP頭部及可能有的TCP選項。
(3)服務器必須確認客戶的SYN,同時自己也得發送一個SYN分節,它含有服務器將在同一連接中發送的數據的初始序列號。服務器以單個分節向客戶發送SYN和對客戶SYN的ACK(表示確認)。
(4)客戶必須確認服務器的SYN。
連接建立的過程至少需要交換三個分組,因此稱之為TCP的三路握手(three-way handshake)。如下圖所示:
上圖中給出的客戶的初始序列號為J,而服務器的初始序列號為K。在ACK里的確認號為發送這個ACK的一端所期待的對端的下一個序列號。
建立TCP連接的日常系統可類比電話系統,客戶(呼叫者)、服務器(被呼叫者):
soket函數等同於有電話可用。呼叫者和被呼叫者都要有一個電話。
bind函數用於告訴其他人你的電話號碼,讓他們可以向你打電話。
listen函數用於打開電話振鈴,它使得你可以聽到一個外來的電話。
accept函數等同於被呼叫者接電話,而且accept函數有來電顯示功能,可以顯示呼叫者的電話號碼。
釋放TCP連接的四次握手:
TCP狀態轉換圖:
TCP連接的建立和終止可以用狀態轉換圖(state transition diagram)來說明。
TCP為一個連接定義了11種狀態(nestat命令的輸出包括這些狀態,它是調試客戶/服務器應用程序有用的工具),並且TCP規則規定如何基於當前狀態及在該狀態下接收的分節從一個狀態轉換到另一個狀態。
我們用實線表示客戶的狀態轉換,虛線表示服務器的狀態轉換。
注意,執行主動關閉的那一端(客戶端)進入TIME_WAIT狀態。該端點停留在這種狀態的持續時間是最長分節生命期(maximum segment lifetime,簡稱MSL)的兩倍,有時候稱之為2MSL。
5、用戶數據報文協議(UDP)
UDP是一種基於IP協議的無連接、不可靠網絡傳輸協議。
UDP協議把應用程序需要傳遞的數據發送出去,不提供發送數據包的順序;接收方不向發送方發送接收的確認信息,如果 出現丟包或者重包的現象,也不會向發送方發送反饋,因此不能保證使用UDP協議的程序發送的數據一定到達了接收方或者到達接收方的數據順序和發送方的一致性。
使用UDP協議傳輸數據的應用程序,必須自己構建發送數據的順序機制和發送接收的確認機制,以此來保證發送數據的正確到達,保證接收數據的順序與發送數據的一致性,也就是說應用程序必須根據UDP的缺點提供解決方案。
UDP協議相對於TCP協議執行時的速度要比TCP快得多,因為UDP協議簡單的多,對系統造成的負載低。
UDP的數據格式:
源端口號和目的端口號分別是一個16位的字段,用來表示發送方和接收方的UDP端口。
UDP數據的傳輸過程:
每個UDP數據報都有一個長度。如果數據報正確地到達其最終目的地,那么數據報的長度將隨數據一道傳送給接收端應用程序。而TCP是一個字節流(byte stream)協議,沒有任何記錄邊界。