什麼是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 ,保證本次連接的所有數據都從網絡中消失。
注:需要C/C Linux服務器開發學習資料私信“資料”(資料包括C/C ,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK等),免費分享
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!