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