深入理解TCP三握四揮

2022-05-18 08:42:12 字數 3427 閱讀 4888

面試中被問到不少次tcp的三握四揮,今天特意來做乙個總結(一些資料是很久前找的,忘了參考的鏈結了)

首先來看一張圖

最初,客戶機a與伺服器b的tcp程序都處於 closed 狀態。

然後由伺服器b先建立tcb(傳輸控制塊),進入到listen 狀態,準備隨時響應客戶請求

下面開始三握:

a的tcp程序建立tcb(傳輸控制塊),然後向b發出連線請求報文段。段首部中的 同步位syn=1,同時選擇乙個初始序列號seq=x;(syn報文段不能攜帶資料,但需要消耗乙個序列號)這時客戶端a進入到 syn-sent(同步已傳送)狀態。

b收到連線請求報文段,如果同意建立連線,則向a傳送確認。在確認報文段中 同步位syn=1、確認位ack=1、確認號ack=x+1(對接收的序列號seq=x的報文段進行確認,並期望接收的下乙個報文段的序號seq=x+1),同時也為自己選擇乙個初始序列號seq=y,這時伺服器b進入 syn-rcvid 狀態。

注:該報文段是ack報文段的同時也是syn報文段,所以該報文段也不能攜帶資料。

a收到b的確認以後,再向b發出確認。確認報文 ack=1、確認號ack=y+1(對接收的序列號seq=y的報文段進行確認,並期望接收的下乙個報文段的序號seq=y+1)。這時a進入到 estab-lished 狀態。當b接收到a的確認後,也進入 estab-lished 狀態。連線建立完成

下面對 同步位syn、確認位ack、確認號ack 以及 三次握手時出現的五個狀態 進行下解釋

同步位syn:在建立連線時用來同步序號;當syn=1,ack=0時,表明這是乙個連線請求報文段。當syn=1,ack=1時,表明這是乙個連線接收報文段;

確認位ack:當ack=1時,確認號ack才生效。在請求建立連線後(第一次握手後),所有的報文段都必須把ack置1。

確認號ack:期望收到的下乙個報文段的第乙個資料位元組的序號,比如:b正確接收到了a傳送過來的乙個報文段,序號是501,資料長度是200位元組;這表明b正確接收到了序號501-700的資料。所以,b期望的下乙個序號是701,於是b在傳送給a的確認報文段中確認號ack=701。

closed:初始關閉狀態

listen:監聽狀態,等待客戶連線

syb-sent:同步已傳送

syn-rcvd:同步已接收

estab-lished:已建立連線

面試問題1:為什麼不是兩次握手?

這主要是為了防止已失效的連線請求報文段突然又傳送到了 b,從而造成資源浪費。

考慮一種異常情況,即 a 發出的第乙個連線請求報文段並沒有丟失,而是在某些網路結點長時間的滯留了,以致延誤到連線釋放以後的某個時間才到達 b。本來這是乙個早已失效的報文段,但 b 收到此失效的連線請求報文段後,就誤認為是 a 又發出了一次新的連線請求,於是就向 a 發出確認報文段,同意建立連線。假定不採用報文握手,那麼只要 b 發出確認,新的連線就建立了。

由於現在 a 並沒有發出建立連線的請求,因此不會理睬 b 的確認,也不會向 b 傳送資料,但 b 卻認為新的運輸連線已經建立了,並一直等待 a 發來資料,b 的許多資源就這樣浪費了。

採用三次握手的辦法,可以防止上述現象的發生,例如在剛才的異常情況下,a 不會向 b 的確認發出確認,b 由於收不到確認,就知道 a 並沒有要求建立連線。

面試問題2:為什麼不是四次握手?

完全可靠的通訊協議是根本不存在的,我們任何的通訊協議都是在接受這樣的現實情況之上進行的。 三次握手後,a 和 b 至少可以確認之前的通訊情況,但無法確認之後的情況。在這個道理上說,無論是四次還是五次或是更多次都是徒勞的。

再來看一張圖

a與b想要斷開連線,需要經過四次揮手

注:fin報文段即使不攜帶資料也要消耗乙個序列。

注:tcp伺服器這時會通知高層應用程序,從a到b這個方向的連線就斷開了,這時tcp連線處於半關閉(half-close)狀態;但b到a這個方向的連線並沒有斷,b任然可以向a傳送資料。

特別注意:確認號ack沒有變,仍然為上次傳送過的確認號u+1。

注:處於time-wait狀態的a必須等待2msl時間後,才會進入closed狀態。msl(maximum segment lifetime)最長報文段壽命,rfc 793 建議設為兩分鐘,對於現在的網路,msl=2分鐘可能太長了一些,我們可根據具體情況使用更小的msl值。

四揮的七個狀態:

estab-lished:已建立連線

fin-wait-1:終止等待1

close-wait:關閉等待

fin-wait-2:終止等待2

last-ack:最後確認

time-wait:時間等待

closed:關閉

面試問題1:為什麼a要等待2msl的時間?

面試問題2:linux伺服器出現大量 time-wait 狀態的tcp連線 的處理方法

通過調整核心引數解決,

vi /etc/sysctl.conf 

編輯檔案,加入以下內容:

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_fin_timeout = 30

然後執行 /sbin/sysctl -p 讓引數生效。 

net.ipv4.tcp_syncookies = 1 表示開啟syn cookies。當出現syn等待佇列溢位時,啟用cookies來處理,可防範少量syn攻擊,預設為0,表示關閉;

net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將 time-wait sockets重新用於新的tcp連線,預設為0,表示關閉;

net.ipv4.tcp_tw_recycle = 1 表示開啟tcp連線中 time-wait sockets的快速**,預設為0,表示關閉。

net.ipv4.tcp_fin_timeout 修改系統預設的 timeout 時間。

面試問題3:為什麼要四次揮手?

注:tcp 是全雙工通訊,因此必須兩個方向分別斷開連線。

面試問題4:為什麼建立連線三次,斷開連線四次?

tcp三握四揮

第一次握手 客戶端傳送syn包給伺服器,syn 1,序列號seq x,客戶端進入syn sent狀態 第二次握手 伺服器收到syn包以後返回報文,ack x 1,ack 1,syn 1,同時生成序列號seq y,進入syn rcvd狀態 第三次握手 客戶端收到伺服器的報文以後,返回給伺服器ack y...

TCP的三握四揮,及與UDP的區別

1.osi模型七層結構 在osi分層 7層 物理層 資料鏈路層 網路層 傳輸層 會話層 表示層 應用層。每一層的協議如下 物理層 rj45 clock ieee802.3 中繼器,集線器,閘道器 資料鏈路 ppp fr hdlc vlan mac 網橋,交換機 網路層 ip icmp arp 位址解...

深入理解TCP

tcp是面向連線的傳輸層層協議,可以為應用層提供可靠的資料傳輸服務。所謂的面向連線並不是真正意思上的連線,只不過是在傳送資料之前,首先得相互握手,也就是說接收方知道你要發資料給它了。而udp是面向無連線的傳輸層協議,並不提供可靠的資料傳輸。有乙個很恰當的比喻 udp傳輸就類似於寫信,接收方事先並不知...