一文搞懂什么是TCP/IP協議
什么是TCP/IP協議?
計算機與網絡設備之間如果要相互通信,雙方就必須基于相同的方法.比如如何探測到通信目標.由哪一邊先發起通信,使用哪種語言進行通信,怎樣結束通信等規則都需要事先確定.不同的硬件,操作系統之間的通信,所有這一切都需要一種規則.而我們就將這種規則稱為協議 (protocol).
也就是說,TCP/IP 是互聯網相關各類協議族的總稱。
TCP/IP 的分層管理
TCP/IP協議里最重要的一點就是分層。TCP/IP協議族按層次分別為 應用層,傳輸層,網絡層,數據鏈路層,物理層。當然也有按不同的模型分為4層或者7層的。
為什么要分層呢?
把 TCP/IP 協議分層之后,如果后期某個地方設計修改,那么就無需全部替換,只需要將變動的層替換。而且從設計上來說,也變得簡單了。處于應用層上的應用可以只考慮分派給自己的任務,而不需要弄清對方在地球上哪個地方,怎樣傳輸,如果確保到達率等問題。
如上圖所示,我們將TCP/IP分為5層,越靠下越接近硬件。我們由下到上來了解一下這些分層。
物理層
該層負責 比特流在節點之間的傳輸,即負責物理傳輸,這一層的協議既與鏈路有關,也與傳輸的介質有關。通俗來說就是把計算機連接起來的物理手段。
數據鏈路層
控制網絡層與物理層之間的通信,主要功能是保證物理線路上進行可靠的數據傳遞。為了保證傳輸,從網絡層接收到的數據被分割成特定的可被物理層傳輸的幀。幀是用來移動數據結構的結構包,他不僅包含原始數據,還包含發送方和接收方的物理地址以及糾錯和控制信息。其中的地址確定了幀將發送到何處,而糾錯和控制信息則確保幀無差錯到達。如果在傳達數據時,接收點檢測到所傳數據中有差錯,就要通知發送方重發這一幀。
網絡層
決定如何將數據從發送方路由到接收方。網絡層通過綜合考慮發送優先權,網絡擁塞程度,服務質量以及可選路由的花費等來決定從網絡中的A節點到B節點的最佳途徑。即建立主機到主機的通信。
傳輸層
該層為兩臺主機上的應用程序提供端到端的通信。傳輸層有兩個傳輸協議:TCP(傳輸控制協議)和 UDP(用戶數據報協議)。其中,TCP是一個可靠的面向連接的協議,udp是不可靠的或者說無連接的協議
應用層
應用程序收到傳輸層的數據后,接下來就要進行解讀。解讀必須事先規定好格式,而應用層就是規定應用程序的數據格式。主要的協議有:HTTP.FTP,Telent等。
TCP與UDP
TCP/UDP 都是傳輸層協議,但是兩者具有不同的特效,同時也具有不同的應用場景。
面向報文
面向報文的傳輸方式是應用層交給UDP多長的報文,UDP發送多長的報文,即一次發送一個報文。因此,應用程序必須選擇合適大小的報文。
面向字節流
雖然應用程序和TCP的交互是一次一個數據塊(大小不等),但TCP把應用程序看成是一連串的無結構的字節流。TCP有一個緩沖,當應該程序傳送的數據塊太長,TCP就可以把它劃分短一些再傳送。
TCP的三次握手與四次揮手
具體過程如下:
第一次握手:建立連接。客戶端發送連接請求報文段,并將syn(標記位)設置為1,Squence Number(數據包序號)(seq)為x,接下來等待服務端確認,客戶端進入SYN_SENT狀態(請求連接);
第二次握手:服務端收到客戶端的 SYN 報文段,對 SYN 報文段進行確認,設置 ack(確認號)為 x+1(即seq+1 ; 同時自己還要發送 SYN 請求信息,將 SYN 設置為1, seq為 y。服務端將上述所有信息放到 SYN+ACK 報文段中,一并發送給客戶端,此時服務器進入 SYN_RECV狀態。
SYN_RECV是指,服務端被動打開后,接收到了客戶端的SYN并且發送了ACK時的狀態。再進一步接收到客戶端的ACK就進入ESTABLISHED狀態。
第三次握手:客戶端收到服務端的 SYN+ACK(確認符) 報文段;然后將 ACK 設置為 y+1,向服務端發送ACK報文段,這個報文段發送完畢后,客戶端和服務端都進入ESTABLISHED(連接成功)狀態,完成TCP 的三次握手。
上面的解釋可能有點不好理解,用《圖解HTTP》中的一副插圖 幫助大家。
當客戶端和服務端通過三次握手建立了 TCP 連接以后,當數據傳送完畢,斷開連接就需要進行TCP的四次揮手。其四次揮手如下所示:
第一次揮手
客戶端設置seq和 ACK ,向服務器發送一個 FIN(終結)報文段。此時,客戶端進入 FIN_WAIT_1 狀態,表示客戶端沒有數據要發送給服務端了。
第二次揮手
服務端收到了客戶端發送的 FIN 報文段,向客戶端回了一個 ACK 報文段。
第三次揮手
服務端向客戶端發送FIN 報文段,請求關閉連接,同時服務端進入 LAST_ACK 狀態。
第四次揮手
客戶端收到服務端發送的 FIN 報文段后,向服務端發送 ACK 報文段,然后客戶端進入 TIME_WAIT 狀態。服務端收到客戶端的 ACK 報文段以后,就關閉連接。此時,客戶端等待 2MSL(指一個片段在網絡中最大的存活時間)后依然沒有收到回復,則說明服務端已經正常關閉,這樣客戶端就可以關閉連接了。
最后再看一下完整的過程:
如果有大量的連接,每次在連接,關閉都要經歷三次握手,四次揮手,這顯然會造成性能低下。因此。Http 有一種叫做 長連接(keepalive connections) 的機制。它可以在傳輸數據后仍保持連接,當客戶端需要再次獲取數據時,直接使用剛剛空閑下來的連接而無需再次握手。
一些問題匯總:
1. 為什么要三次握手?
為了防止已失效的連接請求報文突然又傳送到了服務端,因為產生錯誤。
具體解釋: “已失效的連接請求報文段”產生情況:
client 發出的第一個連接請求報文段并沒有丟失,而是在某個網絡節點長時間滯留,因此導致延誤到連接釋放以后的某個時間才到達 service。如果沒有三次握手,那么此時server收到此失效的連接請求報文段,就誤認為是 client再次發出的一個新的連接請求,于是向 client 發出確認報文段,同意建立連接,而此時 client 并沒有發出建立連接的情況,因此并不會理會服務端的響應,而service將會一直等待client發送數據,因此就會導致這條連接線路白白浪費。
如果此時變成兩次揮手行不行?
這個時候需要明白全雙工與半雙工,再進行回答。比如:
第一次握手: A給B打電話說,你可以聽到我說話嗎?
第二次握手: B收到了A的信息,然后對A說: 我可以聽得到你說話啊,你能聽得到我說話嗎?
第三次握手: A收到了B的信息,然后說可以的,我要給你發信息啦!
在三次握手之后,A和B都能確定這么一件事: 我說的話,你能聽到; 你說的話,我也能聽到。 這樣,就可以開始正常通信了,如果是兩次,那將無法確定。
2. 為什么要四次揮手?
TCP 協議是一種面向連接,可靠,基于字節流的傳輸層通信協議。TCP 是全雙工模式(同一時刻可以同時發送和接收),這就意味著,當主機1發出 FIN 報文段時,只是表示主機1已結沒有數據要發送了,主機1告訴主機2,它的數據已經全部發送完畢;但是,這個時候主機1還是可以接受來自主機2的數據;當主機2返回 ACK報文段時,這個時候就表示主機2也沒有數據要發送了,就會告訴主機1,我也沒有數據要發送了,之后彼此就會中斷這次TCP連接。
3.為什么要等待 2MSL
MSL:報文段最大生存時間,它是任何報文段被丟棄前在網絡內的最長時間
原因如下:
保證TCP協議的全雙工連接能夠可靠關閉
保證這次連接的重復數據從網絡中消息
第一點: 如果主機1直接 關閉,由于IP協議的不可靠性或者其他網絡原因,導致主機2沒有收到主機1最后回復的 ACK。那么主機2就會在超時之后繼續發送 FIN,此時由于主機1已經關閉,就找不到與重發的 FIN 對應的連接。所以,主機1 不是直接進入 關閉,而是TIME_WAIT 狀態。當再次收到 FIN 的時候,能夠保證對方收到 ACK ,最后正確關閉連接。
第二點:如果主機1直接 關閉,然后又再向主機 2 發起一個新連接,我們不能保證這個新連接與剛才關閉的連接端口是不同的。也就是說有可能新連接和老連接的端口號是相同的。一般來說不會發生什么問題,但還是有特殊情況出現;假設新連接和已經關閉的老連接端口號是一樣的,如果前一次連接的某些數據仍然滯留在網絡中( Lost Duplicate ),那些延遲數據在建立新連接之后才到達主機2,由于新連接和老連接的端口號是一樣的,TCP 協議就認為哪個延遲的數據時屬于新連接的,這樣就和真正的新連接的數據包發生混淆了。所以TCP連接要在 TIME_WAIT 狀態等待兩倍 MSL ,保證本次連接的所有數據都從網絡中消失。