前段時間一直在準備面試,本覺得準備的挺好,然而被騰訊面試官問道網絡問題的時候,發現本身對TCP協議的理解真的是停留在表面,不夠深刻。因而本着提升本身的想法,去查了些資料,這裏主要是總結我對TCP創建與斷開鏈接過程的理解。你能夠在這裏看到更好的排版git
在面試中網絡問題是必定會考察的,而TCP協議則是考察網絡知識的重點。常常會被問道的問題以下:github
接下來,我將介紹我理解的TCP三次握手和4次揮手的過程,若是錯誤還請指正,謝謝。面試
首先須要服務器監聽特定的端口,等待客戶端來請求鏈接。當客戶端須要創建鏈接時,客戶端會先向服務器發送syn報文,將報文中syn置爲隨機生成的序號n(這裏假設序號爲1000)。服務器收到同步報文後,會回覆一個ack報文,把ACK位置位n+1(這裏的序號應該爲1001),同時設置syn爲y(這裏假設爲2000)。客戶端收到服務器發送的ack報文後,會回覆一個ACK報文給服務器,其中ACK位置爲y+1(這裏即爲2001)。當服務器收到ACK消息後,即認爲鏈接進入穩定狀態。狀態機與流程圖以下:
服務器
當client從app接收到關閉指令後,client會給server發送FIN消息(代表client不會再給server發送數據),client進入finish-wait-1狀態。server收到finish消息後,回覆確認消息ack給client,自身進入close-wait狀態。client接收到ack消息後,進入到FIN-WAIT-2狀態。而且在此狀態等待服務器發送finish消息。當server接收到app的關閉指令後,server給client發送FIN消息。服務器進入到LAST-ACK狀態。客戶端收到FIN消息後,會回覆ACK消息,同時進入到TIME-WAIT狀態,來等待server收到ack消息,客戶端會在接下來的2MSL(maximum segment lifetime)的時間內保持TIME-WAIT狀態。爲何是2MSL時間呢,一是爲了server有足夠的時間收到ACK消息,並在消息丟失時重發。二是爲了在此鏈接結束後的後續鏈接提供緩衝期。若是不是2倍MSL的話,就可能混合來自不一樣鏈接的數據包,形成消息混亂。狀態機與流程圖以下:網絡
如下爲TCP從創建鏈接到斷開的完整流程圖app
有了上面的介紹,基本可以回答前兩個問題。tcp
看上面ide
看上面ui
首先呢,根本不存在可靠的鏈接,tcp只是提供相對可靠的鏈接。三次握手的主要目的是交換通訊須要的參數,主要是server與client的syn序號,這個序號是用於收發數據的。若是隻有兩次握手的話,當服務器發送ack+syn消息後,就會認爲創建了穩定鏈接,這個時候若是ack+syn丟失了,client並無收到這個消息,那麼客戶端就會認爲鏈接創建不成功,而直接進入close狀態。這樣就會形成,server一直在哪傻等,永遠不會有client來發送數據,這就會形成服務器資源的浪費。至於爲何不是四次握手,是由於握手三次成功之後,就能夠認定當前鏈接是可靠的了,否則的話還須要client與server互相之間發送ack消息,這樣就無休無止了。.net
由於現實中的網絡情況不可預知,好比說客戶端在第一次鏈接時,使用序號爲1爲初始序號進行數據發送,發送了1到30的數據片斷,這個時候由於網絡問題斷開了鏈接。而後客戶端是syn爲1從新創建了新的鏈接,這個時候服務器收到了以前發送的30個字節的數據,服務器就會覺得這30個字節的數據是新發的,這就會致使數據混亂。
說明,本文全部圖片均來自The TCP/IP Guide。
參考資料以下: