TCP為啥設(shè)定為三次握手(兩個角度分析)
如果是4次,多了一次沒啥意義還慢了,如果是兩次握手邏輯可能存在下列問題:
(這兩個方面也可以理解為握手過程中可能出現(xiàn)的問題)
不可靠
TCP協(xié)議是可靠的,那么建立的連接也需要確保是雙向,可靠的; 根據(jù)連接過程分析,只有一方收到了另一方的ack確認(rèn)報文,才能證明那一方的接收功能都正常。
舉下面這個確認(rèn)序號的例子說明 完整的接,收能力的重要性:
(這個抽象的接收功能,在下圖握手過程中實際交換seq初始序號的過程中能體現(xiàn))
第二次握手時,s端發(fā)完ack報文就默認(rèn)進(jìn)入establish建立成功狀態(tài),假設(shè)這個ack報文半路丟了呢?
c端壓根就沒有拿到ack也沒有拿到s端的初始序號,顯然這個鏈接是不可靠的!無法完成后續(xù)數(shù)據(jù)的交互;
產(chǎn)生無效鏈接浪費服務(wù)器資源
假定C端向S端發(fā)送了一個請求,但是該請求因為網(wǎng)絡(luò)原因,在網(wǎng)路中逗留了一會兒,未及時送達(dá)。此時C將再次向S發(fā)送請求,Server接收到請求,發(fā)送確認(rèn)包,完成連接并開始進(jìn)行數(shù)據(jù)傳輸,直到數(shù)據(jù)傳輸完成后,斷開連接。
之后,之前逗留的鏈接到了S端,這就尷尬了,S拿到syn請求,并回應(yīng)了ACK應(yīng)答,然后進(jìn)入establish建立完成狀態(tài),這個鏈接無疑是不合法的,c端早已離去,剩下這個空連接,維持他消耗著S端的資源;
(c端:s端一般是n:1,如果存在上述問題,試想大量空連接有可能被維護(hù),服務(wù)器資源會越來越吃緊從而導(dǎo)致更嚴(yán)重的問題)
TCP為啥四次揮手
客戶端或服務(wù)器均可主動發(fā)起揮手動作,調(diào)用close()即可,為了方便理解,假設(shè)C端先發(fā)起,S端作為被動斷開的一方;
其實我們?nèi)挝帐值倪^程中的第二次,是將四次揮手中的中間兩次合并優(yōu)化了,那為啥TCP是四次揮手?其實這個說法有歧義,因為TCP多數(shù)情況下是4次揮手,但是也存在3次揮手的情況:
服務(wù)端有剩余數(shù)據(jù)需要發(fā)送–四次揮手(多數(shù)情況)
因為多數(shù)情況下,當(dāng)c端主動與s端斷開之后,s端不一定立即就與c端斷開連接,可能還會有一些數(shù)據(jù)要發(fā)給c端,所以還會保持鏈接一段時間;
(當(dāng)然TCP有?;顧C制,會通過設(shè)定時間間隔反復(fù)發(fā)送活性探測數(shù)據(jù)包,如果一段時間內(nèi)沒有響應(yīng)或者一定的次數(shù)之后,就會斷開這個鏈接釋放資源)
服務(wù)端無剩余數(shù)據(jù)發(fā)送–捎帶應(yīng)答–四次變?nèi)?少數(shù)情況)
在少數(shù)情況下,c端主動斷開,s端恰巧也沒啥要發(fā)的,也需要立即斷開,那么TCP的捎帶應(yīng)答機制,就將四次揮手的中間兩次進(jìn)行合并,這時候四次揮手就變成了三次揮手;
四次揮手可能出現(xiàn)的問題
客戶端或服務(wù)器均可主動發(fā)起揮手動作,調(diào)用close()即可,為了方便理解,假設(shè)C端先發(fā)起,S端作為被動斷開的一方;
可能出現(xiàn)大量的TIME_WAIT
TIME_WAIT狀態(tài)是C端收到了S端主動發(fā)送fin請求后,向S端發(fā)回了ACK確認(rèn)斷開報文之后出現(xiàn)的,需要保持2*MSL時間確保最后一個ACK報文能夠到達(dá)S端,雙方正常關(guān)閉; (設(shè)計成2*MSL的原因是確保響應(yīng)ACK的傳輸時間和如果這個ACK丟失,S端重新發(fā)送FIN請求斷開的時間)可見,msl一定是大于超時重傳的時間的;
解決:文章來源:http://www.zghlxwxcb.cn/news/detail-777890.html
一臺主機出現(xiàn)大量的TIME_WAIT證明這臺主機上發(fā)起大量的主動關(guān)閉連接(常見于一些爬蟲服務(wù)器)
這時候我們應(yīng)該調(diào)整TIME_WAIT的等待時間(linux centos當(dāng)時測試默認(rèn)是60s),或者開啟套接字地址重用選項
(否則這個端口號就被占用了,這個主機其他的服務(wù)就用不了這個端口號了…Bind Error)
可能出現(xiàn)大量的CLOSE_WAIT
CLOSE_WAIT是S端同意C端的fin請求之后進(jìn)入的狀態(tài),等待上層程序進(jìn)一步處理(比如發(fā)送剩余數(shù)據(jù));
解決:
如果S端產(chǎn)生大量的CLOSE_WAIT,可能是內(nèi)核斷開連接后,S端忘記調(diào)用close,這就是我們程序員的疏忽了,寫了個小bug;文章來源地址http://www.zghlxwxcb.cn/news/detail-777890.html
到了這里,關(guān)于TCP為什么是三次握手和四次揮手以及可能出現(xiàn)的問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!