引言
前段時間一直在準(zhǔn)備面試,本以為準(zhǔn)備的挺好,然而被騰訊面試官問道網(wǎng)絡(luò)問題的時候,發(fā)現(xiàn)自己對TCP協(xié)議的理解真的是停留在表面,不夠深入。于是本著提高自己的想法,去查了些資料,這里主要是總結(jié)我對TCP建立與斷開連接過程的理解。你可以在
這里
<https://wukongcoo1.github.io/2019/09/02/TCP%E7%9A%84%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E4%B8%8E%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/>
看到更好的排版
常見題目
在面試中網(wǎng)絡(luò)問題是一定會考察的,而TCP協(xié)議則是考察網(wǎng)絡(luò)知識的重點。經(jīng)常會被問道的問題如下:
* 請講一下TCP協(xié)議建立連接的過程
* 請介紹TCP協(xié)議中的三次握手和四次揮手是怎么樣的
* 為什么TCP協(xié)議要三次握手來確立連接,而不是兩次,也不是4次
* TCP連接發(fā)起是的syn序號為什么不能從同一個序號開始,比如說1
接下來,我將介紹我理解的TCP三次握手和4次揮手的過程,如果錯誤還請指正,謝謝。
TCP協(xié)議
三次握手過程
首先需要服務(wù)器監(jiān)聽特定的端口,等待客戶端來請求連接。當(dāng)客戶端需要建立連接時,客戶端會先向服務(wù)器發(fā)送syn報文,將報文中syn置為隨機生成的序號n(這里假設(shè)序號為1000)。服務(wù)器收到同步報文后,會回復(fù)一個ack報文,把ACK位置位n+1(這里的序號應(yīng)該為1001),同時設(shè)置syn為y(這里假設(shè)為2000)。客戶端收到服務(wù)器發(fā)送的ack報文后,會回復(fù)一個ACK報文給服務(wù)器,其中ACK位置為y+1(這里即為2001)。當(dāng)服務(wù)器收到ACK消息后,即認(rèn)為連接進入穩(wěn)定狀態(tài)。狀態(tài)機與流程圖如下:
四次揮手過程
當(dāng)client從app接收到關(guān)閉指令后,client會給server發(fā)送FIN消息(表明client不會再給server發(fā)送數(shù)據(jù)),client進入finish-wait-1狀態(tài)。server收到finish消息后,回復(fù)確認(rèn)消息ack給client,自身進入close-wait狀態(tài)。client接收到ack消息后,進入到FIN-WAIT-2狀態(tài)。并且在此狀態(tài)等待服務(wù)器發(fā)送finish消息。當(dāng)server接收到app的關(guān)閉指令后,server給client發(fā)送FIN消息。服務(wù)器進入到LAST-ACK狀態(tài)。客戶端收到FIN消息后,會回復(fù)ACK消息,同時進入到TIME-WAIT狀態(tài),來等待server收到ack消息,客戶端會在接下來的2MSL(maximum
segment
lifetime)的時間內(nèi)保持TIME-WAIT狀態(tài)。為什么是2MSL時間呢,一是為了server有足夠的時間收到ACK消息,并在消息丟失時重發(fā)。二是為了在此連接結(jié)束后的后續(xù)連接提供緩沖期。如果不是2倍MSL的話,就可能混合來自不同連接的數(shù)據(jù)包,造成消息混亂。狀態(tài)機與流程圖如下:
完整過程
以下為TCP從建立連接到斷開的完整流程圖
開始答題
有了上面的介紹,基本能夠回答前兩個問題。
請講一下TCP協(xié)議建立連接的過程
看上面
請介紹TCP協(xié)議中的三次握手和四次揮手是怎么樣的
看上面
為什么TCP協(xié)議要三次握手來確立連接,而不是兩次,也不是4次
首先呢,根本不存在可靠的連接,tcp只是提供相對可靠的連接。三次握手的主要目的是交換通信需要的參數(shù),主要是server與client的syn序號,這個序號是用于收發(fā)數(shù)據(jù)的。如果只有兩次握手的話,當(dāng)服務(wù)器發(fā)送ack+syn消息后,就會認(rèn)為建立了穩(wěn)定連接,這個時候如果ack+syn丟失了,client并沒有收到這個消息,那么客戶端就會認(rèn)為連接建立不成功,而直接進入close狀態(tài)。這樣就會造成,server一直在哪傻等,永遠(yuǎn)不會有client來發(fā)送數(shù)據(jù),這就會造成服務(wù)器資源的浪費。至于為什么不是四次握手,是因為握手三次成功以后,就可以認(rèn)定當(dāng)前連接是可靠的了,不然的話還需要client與server互相之間發(fā)送ack消息,這樣就無休無止了。
TCP連接發(fā)起是的syn序號為什么不能從同一個序號開始,比如說1
因為現(xiàn)實中的網(wǎng)絡(luò)狀況不可預(yù)知,比如說客戶端在第一次連接時,使用序號為1為初始序號進行數(shù)據(jù)發(fā)送,發(fā)送了1到30的數(shù)據(jù)片段,這個時候因為網(wǎng)絡(luò)問題斷開了連接。然后客戶端是syn為1重新建立了新的連接,這個時候服務(wù)器收到了之前發(fā)送的30個字節(jié)的數(shù)據(jù),服務(wù)器就會以為這30個字節(jié)的數(shù)據(jù)是新發(fā)的,這就會導(dǎo)致數(shù)據(jù)混亂。
參考資料
說明,本文所有圖片均來自The TCP/IP Guide
<http://www.tcpipguide.com/free/t_TCPConnectionTermination-2.htm>。
參考資料如下:
The TCP/IP Guide
<http://www.tcpipguide.com/free/t_TCPConnectionTermination-2.htm>
TCP為什么需要3次握手與4次揮手 <https://blog.csdn.net/xifeijian/article/details/12777187>
TCP三次握手四次揮手詳解 <https://zhuanlan.zhihu.com/p/40013850>
熱門工具 換一換