您好,登錄后才能下訂單哦!
本篇文章為大家展示了計(jì)算機(jī)網(wǎng)絡(luò)傳輸協(xié)議TCP三次握手與四次揮手原理是怎樣的,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
我們之前在 傳輸層協(xié)議TCP與UDP 中詳細(xì)介紹了UDP協(xié)議和TCP協(xié)議格式以及他們各自的特點(diǎn),我們知道TCP協(xié)議是面向連接的,那面向連接就得需要做建立連接,維護(hù)連接,斷開(kāi)連接這些工作。
[CLOSED->LISTEN] 服務(wù)器調(diào)用listen后就進(jìn)入LISTEN狀態(tài),等待客戶端向自己發(fā)起連接
[LISTEN->SYN_RCVD] 一旦監(jiān)聽(tīng)到連接請(qǐng)求(同步報(bào)文段),就會(huì)將該連接放入內(nèi)核中維護(hù)的連接等待隊(duì)列中,并向客戶端發(fā)送SYN+ACK報(bào)文確認(rèn)已收到看客戶端的連接請(qǐng)求
[SYN_RCVD->ESTABLISHED] 服務(wù)器一旦收到了客戶端的確認(rèn)報(bào)文,就進(jìn)入ESTABLISHED狀態(tài),就可以進(jìn)行讀寫數(shù)據(jù)了
[ESTABLISHED->CLOSE_WAIT] 當(dāng)客戶端主動(dòng)關(guān)閉連接(調(diào)用close),服務(wù)器收到客戶端發(fā)送的結(jié)束報(bào)文段FIN,服務(wù)器向客戶端返回確認(rèn)收到關(guān)閉連接的報(bào)文后,就會(huì)進(jìn)入CLOSE_WAIT
[CLOSE_WAIT->LAST_ACK] 當(dāng)服務(wù)器進(jìn)入CLOSE_WAIT狀態(tài)時(shí),說(shuō)明服務(wù)器已經(jīng)開(kāi)始準(zhǔn)備關(guān)閉連接(但是需要先處理完之前的數(shù)據(jù)),當(dāng)服務(wù)器真正調(diào)用close關(guān)閉連接時(shí),會(huì)向客戶端發(fā)送FIN報(bào)文,自己則進(jìn)入LAST_ACK狀態(tài),等待最后一個(gè)ACK的到來(lái)(這里的ACK是指客戶端對(duì)于服務(wù)器發(fā)送的FIN的響應(yīng)報(bào)文)
[LAST_ACK->CLOSED] 服務(wù)器收到了客戶端對(duì)FIN報(bào)文的響應(yīng)ACK,至此服務(wù)器關(guān)閉連接成功
[CLOSED->SYN_SEND] 客戶端調(diào)用connect,向服務(wù)器發(fā)送同步報(bào)文段,表示想與服務(wù)器建立連接,自己進(jìn)入SYN_SEND狀態(tài)等待服務(wù)器的響應(yīng)
[SYN_SEND->ESTABLISHED] connect調(diào)用成功,客戶端收到服務(wù)器的響應(yīng)報(bào)文ACK,進(jìn)入ESTABLISHED狀態(tài),可以讀寫數(shù)據(jù)
[ESTABLISHED->FIN_WIAT_1] 客戶端主動(dòng)調(diào)用close,向服務(wù)器發(fā)送結(jié)束報(bào)文段,自己進(jìn)入FIN_WAIT_1狀態(tài),等待服務(wù)器的響應(yīng)
[FIN_WAIT_1->FIN_WAIT_2]客戶端收到服務(wù)器對(duì)結(jié)束報(bào)文段的確認(rèn),則進(jìn)入FIN_WAIT_2狀態(tài),開(kāi)始等待服務(wù)器的結(jié)束報(bào)文段
[FIN_WAIT_2 -> TIME_WAIT] 客戶端收到服務(wù)器發(fā)來(lái)的結(jié)束報(bào)文段, 進(jìn)入TIME_WAIT, 并發(fā)出對(duì)服務(wù)器發(fā)送的結(jié)束報(bào)文的的響應(yīng) LAST_ACK;
[TIME_WAIT -> CLOSED] 客戶端要等待一個(gè)2MSL(Max Segment Life, 報(bào)文最大生存時(shí)間)的時(shí)間, 才會(huì)進(jìn)入CLOSED狀態(tài)(因?yàn)橐乐狗?wù)器沒(méi)有收到LASK_ACK,需要進(jìn)行重發(fā)的情況).
答:3次握手完成兩個(gè)重要的功能,既要雙方做好發(fā)送數(shù)據(jù)的準(zhǔn)備工作(雙方都知道彼此已準(zhǔn)備好),也要允許雙方就初始序列號(hào)進(jìn)行協(xié)商,這個(gè)序列號(hào)在握手過(guò)程中被發(fā)送和確認(rèn)。
現(xiàn)在把三次握手改成僅需要兩次握手,死鎖是可能發(fā)生的。作為例子,考慮計(jì)算機(jī)S和C之間的通信,假定C給S發(fā)送一個(gè)連接請(qǐng)求分組,S收到了這個(gè)分組,并發(fā)送了確認(rèn)應(yīng)答分組。
按照兩次握手的協(xié)定,S認(rèn)為連接已經(jīng)成功地建立了,可以開(kāi)始發(fā)送數(shù)據(jù)分組。
可是,C在S的應(yīng)答分組在傳輸中被丟失的情況下,將不知道S 是否已準(zhǔn)備好,不知道S建立什么樣的序列號(hào),C甚至懷疑S是否收到自己的連接請(qǐng)求分組。
在這種情況下,C認(rèn)為連接還未建立成功,將忽略S發(fā)來(lái)的任何數(shù)據(jù)分 組,只等待連接確認(rèn)應(yīng)答分組。而S在發(fā)出的分組超時(shí)后,重復(fù)發(fā)送同樣的分組。這樣就形成了死鎖。
兩次握手還可能造成服務(wù)器資源的浪費(fèi),怎么說(shuō)呢,再舉個(gè)栗子,假設(shè)今天C向S發(fā)送了一個(gè)連接請(qǐng)求,并等待S的響應(yīng),S給C發(fā)送ACK之后,就認(rèn)為連接已經(jīng)建立,我們知道連接建立之后是需要維護(hù)這個(gè)連接的,此時(shí)S的操作系統(tǒng)就需要分配資源和空間來(lái)維護(hù)這個(gè)連接,那假設(shè)S給C的響應(yīng)丟失了,C并未收到響應(yīng)則認(rèn)為連接沒(méi)有建立成功,不能正常通信,此時(shí)S維護(hù)的連接就是一個(gè)失敗的連接,不能成功通信,那假設(shè)今天由100萬(wàn)個(gè)客戶端向S這個(gè)服務(wù)器發(fā)送連接請(qǐng)求,結(jié)果都沒(méi)有收到響應(yīng),此時(shí)S就維護(hù)了100萬(wàn)個(gè)無(wú)用的連接,浪費(fèi)服務(wù)器的資源
答:因?yàn)楫?dāng)Server端收到Client端的SYN連接請(qǐng)求報(bào)文后,可以直接發(fā)送SYN+ACK報(bào)文。其中ACK報(bào)文是用來(lái)應(yīng)答的,SYN報(bào)文是用來(lái)同步的。
但是關(guān)閉連接時(shí),當(dāng)Server端收到FIN報(bào)文時(shí),很可能并不會(huì)立即關(guān)閉SOCKET,所以只能先回復(fù)一個(gè)ACK報(bào)文,告訴Client端,“你發(fā)的FIN報(bào)文我收到了”。
只有等到Server端所有的報(bào)文都發(fā)送完了,所有的數(shù)據(jù)也處理完了之后,Server端才能發(fā)送FIN報(bào)文表示自己能夠斷開(kāi)連接,因此不能一起發(fā)送。故需要四步握手。
答:TCP連接是有一個(gè)?;钣?jì)時(shí)器,顯然,客戶端如果出現(xiàn)故障,服務(wù)器不能一直等下去,白白浪費(fèi)資源。
服務(wù)器每收到一次客戶端的請(qǐng)求后都會(huì)重新復(fù)位這個(gè)計(jì)時(shí)器,時(shí)間通常是設(shè)置為2小時(shí),若兩小時(shí)還沒(méi)有收到客戶端的任何數(shù)據(jù),服務(wù)器就會(huì)發(fā)送一個(gè)探測(cè)報(bào)文段,以后每隔75秒鐘發(fā)送一次。
若一連發(fā)送10個(gè)探測(cè)報(bào)文仍然沒(méi)反應(yīng),服務(wù)器就認(rèn)為客戶端出了故障,接著就關(guān)閉連接。
現(xiàn)在做一個(gè)測(cè)試,首先啟動(dòng)server,然后啟動(dòng)client,然后用Ctrl-C使server終止,這時(shí)馬上再運(yùn)行server, 結(jié)果是:
這是因?yàn)?雖然server的應(yīng)用程序終止了,但TCP協(xié)議層的連接并沒(méi)有完全斷開(kāi),因此不能再次監(jiān) 聽(tīng)同樣的server端口.我們用netstat命令查看一下:
TCP協(xié)議規(guī)定,主動(dòng)關(guān)閉連接的一方要處于TIME_ WAIT狀態(tài),等待兩個(gè)MSL(maximum segment lifetime)的時(shí)間后才能回到CLOSED狀態(tài).
我們使用Ctrl-C終止了server, 所以server是主動(dòng)關(guān)閉連接的一方, 在TIME_WAIT期間仍然不能再次監(jiān)聽(tīng)同樣的server端口;
MSL在RFC1122中規(guī)定為兩分鐘,但是各操作系統(tǒng)的實(shí)現(xiàn)不同, 在Centos7上默認(rèn)配置的值是60s;
可以通過(guò) cat /proc/sys/net/ipv4/tcp_fin_timeout
查看msl的值
MSL是TCP報(bào)文的最大生存時(shí)間, 因此TIME_WAIT持續(xù)存在2MSL的話就能保證在兩個(gè)傳輸方向上的尚未被接收或遲到的報(bào)文段都已經(jīng)消失(否則服務(wù)器立刻重啟, 可能會(huì)收到來(lái)自上一個(gè)進(jìn)程的遲到的數(shù)據(jù), 但是這種數(shù)據(jù)很可能是錯(cuò)誤的);
同時(shí)也是在理論上保證最后一個(gè)報(bào)文可靠到達(dá)(假設(shè)最后一個(gè)ACK丟失, 那么服務(wù)器會(huì)再重發(fā)一個(gè)FIN. 這時(shí)雖然客戶端的進(jìn)程不在了, 但是TCP連接還在, 仍然可以重發(fā)LAST_ACK);
在server的TCP連接沒(méi)有完全斷開(kāi)之前不允許重新監(jiān)聽(tīng), 某些情況下可能是不合理的
服務(wù)器需要處理非常大量的客戶端的連接(每個(gè)連接的生存時(shí)間可能很短, 但是每秒都有很大數(shù)量的客戶端來(lái)請(qǐng)求).
這個(gè)時(shí)候如果由服務(wù)器端主動(dòng)關(guān)閉連接(比如某些客戶端不活躍, 就需要被服務(wù)器端主動(dòng)清理掉), 就會(huì)產(chǎn)生大量TIME_WAIT連接.
由于我們的請(qǐng)求量很大, 就可能導(dǎo)致TIME_WAIT的連接數(shù)很多, 每個(gè)連接都會(huì)占用一個(gè)通信五元組(源ip,源端口, 目的ip, 目的端口, 協(xié)議). 其中服務(wù)器的ip和端口和協(xié)議是固定的. 如果新來(lái)的客戶端連接的ip和端口號(hào)和TIME_WAIT占用的鏈接重復(fù)了,就會(huì)出現(xiàn)問(wèn)題.
使用setsockopt() 設(shè)置socket描述符的 選項(xiàng)SO_REUSEADDR為1, 表示允許創(chuàng)建端口號(hào)相同但I(xiàn)P地址不同的多個(gè)socket描述符
加上了setsockopt之后,ctrl+c終止服務(wù)器之后也可以馬上啟動(dòng)服務(wù)器
上述內(nèi)容就是計(jì)算機(jī)網(wǎng)絡(luò)傳輸協(xié)議TCP三次握手與四次揮手原理是怎樣的,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。