TCP三次握手與四次揮手詳解(最全面)

TCP的三次握手與四次揮手

TCP報文段的首部格式

  • 源端口和目的端口字段各佔 2個字節。端口是運輸層與應用層的服務接口。運輸層的複用和分用功能都要經過端口才能實現。
  • 序號字段4字節。TCP鏈接中傳送的數據流中的每個字節都編上一個序號。序號字段的值則指的是本報文段所發送的數據的第一個字節的序號。
  • 確認號字段佔 4字節,是指望收到對方的下一個報文段的數據的第一個字節的序號
  • 數據偏移(即首部長度)佔 4位,它指出TCP報文段的數據起始處距離TCP報文段的起始處有多遠。「數據偏移」的單位是32位字(以4字節爲計算單位)
  • 保留字段6位,保留爲從此使用,但目前應置爲0。
  • 緊急URGURG= 1 時,代表緊急指針字段有效。它告訴系統此報文段中有緊急數據,應儘快傳送(至關於高優先級的數據)。
  • 確認 ACK 只有當ACK= 1 時確認號字段才有效。當ACK= 0 時,確認號無效
  • 推送 PSH(PuSH)接收TCP收到PSH= 1 的報文段,就儘快地交付接收應用進程,而再也不等到整個緩存都填滿了後再向上交付。
  • 復位 RST(ReSeT)當RST= 1 時,代表TCP鏈接中出現嚴重差錯(如因爲主機崩潰或其餘緣由),必須釋放鏈接,而後再從新創建運輸鏈接。
  • 同步 SYN 同步SYN= 1 表示這是一個鏈接請求或鏈接接受報文。
  • 終止 FIN(FINis) 用來釋放一個鏈接。FIN= 1 代表此報文段的發送端的數據已發送完畢,並要求釋放運輸鏈接。
  • 窗口字段佔2字節,用來讓對方設置發送窗口的依據,單位爲字節
  • 檢驗和佔2字節。檢驗和字段檢驗的範圍包括首部和數據這兩部分。在計算檢驗和時,要在TCP報文段的前面加上12字節的僞首部。
  • 緊急指針字段佔16位,指出在本報文段中緊急數據共有多少個字節(緊急數據放在本報文段數據的最前面)。
  • 選項字段長度可變。TCP最初只規定了一種選項,即最大報文段長度 MSS。MSS告訴對方TCP:「個人緩存所能接收的報文段的數據字段的最大長度是MSS個字節。
  • 填充字段這是爲了使整個首部長度是4字節的整數倍

TCP的工做原理

注意:算法

  • 在發送完一個分組後,必須暫時保留已發送的分組的副本。緩存

  • 分組和確認分組都必須進行編號。服務器

  • 超時計時器的重傳時間應當比數據在分組傳輸的平均往返時間更長一些。網絡

TCP 的流量控制

通常說來,咱們老是但願數據傳輸得更快一些。但若是發送方把數據發送得過快,接收方就可能來不及接收,這就會形成數據的丟失。tcp

流量控制(flow control)就是讓發送方的發送速率不要太快,既要讓接收方來得及接收,也不要使網絡發生擁塞。性能

利用滑動窗口機制能夠很方便地在 TCP 鏈接上實現流量控制。指針

舉個例子:blog

TCP的擁塞控制

在某段時間,若對網絡中某資源的需求超過了該資源所能提供的可用部分,網絡的性能就要變壞——產生擁塞(congestion)。接口

出現資源擁塞的條件:

​ 對資源需求的總和 > 可用資源

若網絡中有許多資源同時產生擁塞,網絡的性能就要明顯變壞,整個網絡的吞吐量將隨輸入負荷的增大而降低。

擁塞控制與流量控制的關係

擁塞控制所要作的都有一個前提,就是網絡可以承受現有的網絡負荷。

擁塞控制是一個全局性的過程,涉及到全部的主機、全部的路由器,以及與下降網絡傳輸性能有關的全部因素。

流量控制每每指在給定的發送端和接收端之間的點對點通訊量的控制。

流量控制所要作的就是抑制發送端發送數據的速率,以便使接收端來得及接收。

擁塞控制所起的做用

慢開始和擁塞避免

發送方維持一個叫作擁塞窗口 cwnd (congestion window)的狀態變量。擁塞窗口的大小取決於網絡的擁塞程度,而且動態地在變化。

發送方讓本身的發送窗口等於擁塞窗口。如再考慮到接收方的接收能力,則發送窗口還可能小於擁塞窗口。

發送方控制擁塞窗口的原則是:只要網絡沒有出現擁塞,擁塞窗口就再增大一些,以便把更多的分組發送出去。但只要網絡出現擁塞,擁塞窗口就減少一些,以減小注入到網絡中的分組數。

慢開始算法的原理

在主機剛剛開始發送報文段時可先設置擁塞窗口 cwnd = 1,即設置爲一個最大報文段 MSS 的數值。

在每收到一個對新的報文段的確認後,將擁塞窗口加 1,即增長一個 MSS 的數值。

用這樣的方法逐步增大發送端的擁塞窗口 cwnd,可使分組注入到網絡的速率更加合理。

發送方每收到一個對新報文段的確認(重傳的不算在內)就使 cwnd加

三次握手創建TCP鏈接

第一次握手:A 的 TCP 向 B 發出鏈接請求報文段,其首部中的同步位 SYN = 1,並選擇序號 seq = x,代表傳送數據時的第一個數據字節的序號是 x。

第二次握手:B 的 TCP 收到鏈接請求報文段後,如贊成,則發回確認。B 在確認報文段中應使 SYN = 1,使 ACK = 1,其確認號ack = x + 1,本身選擇的序號 seq = y。

第三次握手:

  • A 收到此報文段後向 B 給出確認,其 ACK = 1,確認號 ack = y + 1。A的TCP通知上層應用進程,鏈接已經創建。
  • B 的 TCP 收到主機 A 的確認後,也通知其上層應用進程:TCP 鏈接已經創建。

四次揮手釋放TCP鏈接

第一次揮手:

  • 數據傳輸結束後,通訊的雙方均可釋放鏈接。如今 A 的應用進程先向其 TCP 發出鏈接釋放報文段,並中止再發送數據,主動關閉 TCP 鏈接。

  • A 把鏈接釋放報文段首部的 FIN = 1,其序號seq = u,等待 B 的確認。

第二次揮手:

  • B 發出確認,確認號 ack = u + 1,而這個報文段本身的序號 seq = v。
  • TCP 服務器進程通知高層應用進程。
  • 從 A 到 B 這個方向的鏈接就釋放了,TCP 鏈接處於半關閉狀態,B若發送數據,A仍是要接收的

第三次揮手:

  • 若 B 已經沒有要向 A 發送的數據,其應用進程就通知 TCP 釋放鏈接

第四次揮手:

  • A 收到鏈接釋放報文段後,必須發出確認。 •在確認報文段中 ACK = 1,確認號 ack = w + 1,本身的序號 seq = u + 1。

常見面試題

爲何TCP鏈接的時候是三次握手,關閉的時候倒是四次握手?

答:

由於當Server端收到Client端的SYN鏈接請求報文後,能夠直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。

可是關閉鏈接時,當Server端收到FIN報文時,極可能並不會當即關閉SOCKET,因此只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端全部的報文都發送完了,我才能發送FIN報文,所以不能一塊兒發送。故須要四步握手。

爲何不能用兩次握手進行鏈接?

答:

3次握手完成兩個重要的功能,既要雙方作好發送數據的準備工做(雙方都知道彼此已準備好),也要容許雙方就初始序列號進行協商,這個序列號在握手過程當中被髮送和確認。

如今把三次握手改爲僅須要兩次握手,死鎖是可能發生的。做爲例子,考慮計算機S和C之間的通訊,假定C給S發送一個鏈接請求分組,S收到了這個分組,並 發送了確認應答分組。按照兩次握手的協定,S認爲鏈接已經成功地創建了,能夠開始發送數據分組。但是,C在S的應答分組在傳輸中被丟失的狀況下,將不知道S 是否已準備好,不知道S創建什麼樣的序列號,C甚至懷疑S是否收到本身的鏈接請求分組。在這種狀況下,C認爲鏈接還未創建成功,將忽略S發來的任何數據分 組,只等待鏈接確認應答分組。而S在發出的分組超時後,重複發送一樣的分組。這樣就造成了死鎖。

若是已經創建了鏈接,可是客戶端忽然出現故障了怎麼辦?

答:

TCP還設有一個保活計時器,顯然,客戶端若是出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求後都會從新復位這個計時器,時間一般是設置爲2小時,若兩小時尚未收到客戶端的任何數據,服務器就會發送一個探測報文段,之後每隔75秒鐘發送一次。若一連發送10個探測報文仍然沒反應,服務器就認爲客戶端出了故障,接着就關閉鏈接。

爲何TIME_WAIT狀態須要通過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?

答:

雖然按道理,四個報文都發送完畢,咱們能夠直接進入CLOSE狀態了,可是咱們必須假象網絡是不可靠的,有能夠最後一個ACK丟失。因此TIME_WAIT狀態就是用來重發可能丟失的ACK報文。在Client發送出最後的ACK回覆,但該ACK可能丟失。Server若是沒有收到ACK,將不斷重複發送FIN片斷。因此Client不能當即關閉,它必須確認Server接收到了該ACK。Client會在發送出ACK以後進入到TIME_WAIT狀態。Client會設置一個計時器,等待2MSL的時間。若是在該時間內再次收到FIN,那麼Client會重發ACK並再次等待2MSL。所謂的2MSL是兩倍的MSL(Maximum Segment Lifetime)。MSL指一個片斷在網絡中最大的存活時間,2MSL就是一個發送和一個回覆所需的最大時間。若是直到2MSL,Client都沒有再次收到FIN,那麼Client推斷ACK已經被成功接收,則結束TCP鏈接。

相關文章
相關標籤/搜索