1. 程式人生 > 程式設計 >計算機網路傳輸協議TCP三次握手與四次揮手原理

計算機網路傳輸協議TCP三次握手與四次揮手原理

目錄
  • TCP三次握手四次揮手
    • 伺服器狀態轉換
    • 客戶端狀態轉換
    • TCP狀態轉換圖
  • TCP中常見的面試題
    • 為什麼是三次握手,不是一次或者兩次
    • 為什麼是三次握手,四次揮手
    • 如果已經建立了連線,但是客戶端突然出現故障了怎麼辦?
    • 為什麼會有TIME_WAIT狀態
      • 我們來想一想,為什麼TIME_WAIT的時間是2MSL
    • 解決TIME_WAIT狀態引起的bind失敗的方法

    TCP三次握手四次揮手

    我們之前在 傳輸層協議TCP與UDP 中詳細介紹了UDP協議和TCP協議格式以及他們各自的特點,我們知道TCP協議是面向連線的,那面向連線就得需要做建立連線,維護連線,斷開連線這些工作。

    TCP三次握手四次揮手

    伺服器狀態轉換

    [CLOSED->LISTEN] 伺服器呼叫listen後就進入LISTEN狀態,等待客戶端向自己發起連線

    [LISTEN->SYN_RCVD] 一旦監聽到連線請求(同步報文段),就會將該連線放入核心中維護的連線等待佇列中,並向客戶端傳送SYN+ACK報文確認已收到看客戶端的連線請求

    [SYN_RCVD->ESTABLISHED] 伺服器一旦收到了客戶端的確認報文,就進入ESTABLISHED狀態,就可以進行讀寫資料了

    kBNOMQlGXt

    [ESTABLISHED->CLOSE_WAIT] 當客戶端主動關閉連線(呼叫close),伺服器收到客戶端傳送的結束報文段FIN,伺服器向客戶端返回確認收到關閉連線的報文後,就會進入CLOSE_WAIT

    [CLOSE_WAIT->LAST_ACK] 當伺服器進入CLOSE_WAIT狀態時,說明伺服器已經開始準備關閉連線(但是需要先處理完之前的資料),當伺服器真正呼叫close關閉連線時,會向客戶端傳送FIN報文,自己則進入LAST_ACK狀態,等待最後一個ACK的到來(這裡的ACK是指客戶端對於伺服器傳送的FIN的響應報文)

    [LAST_ACK->CLOSED] 伺服器收到了客戶端對FIN報文的響應ACK,至此伺服器關閉連線成功

    客戶端狀態轉換

    [CLOSED->SYN_SEND] 客戶端呼叫connect,向伺服器傳送同步報文段,表示想與伺服器建立連線,自己進入SYN_SEND狀態等待伺服器的響應

    [SYN_SEND->ESTABLISHED] connect呼叫成功,客戶端收到伺服器的響應報文ACK,進入ESTABLISHED狀態,可以讀寫資料

    [ESTABLISHED->FIN_WIAT_1] 客戶端主動呼叫close,向伺服器傳送結束報文段,自己進入FIN_WAIT_1狀態,等待伺服器的響應

    [FIN_WAIT_1->FIN_WAIT_2]客戶端收到伺服器對結束報文段的確認,則進入FIN_WAIT_2狀態,開始等待伺服器的結束報文段

    [FIN_WAIT_2 -> TIME_WAIT] 客戶端收到伺服器發來的結束報文段,進入TIME_WAIT,併發出對伺服器傳送的結束報文的的響應 LAST_ACK;

    [TIME_WAIT -> CLOSED] 客戶端要等待一個2MSL(Max Segment Life,報文最大生存時間)的時間,才會進入CLOSED狀態(因為要防止伺服器沒有收到LASK_ACK,需要進行重發的情況).

    TCP狀態轉換圖

    TCP狀態轉換圖

    TCP中常見的面試題

    為什麼是三次握手,不是一次或者兩次

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

    • 現在把三次握手改成僅需要兩次握手,死鎖是可能發生的。作為例子,考慮計算機S和C之間的通訊,假定C給S傳送一個連線請求分組,S收到了這個分組,併發送了確認應答分組。
      按照兩次握手的協定,S認為連線已經成功地建立了,可以開始傳送資料分組。
      可是,C在S的應答分組在傳輸中被丟失的情況下,將不知道S 是否已準備好,不知道S建立什麼樣的序列號,C甚至懷疑S是否收到自己的連線請求分組。
      在這種情況下,C認為連線還未建立成功,將忽略S發來的任何資料分 組,只等待連線確認應答分組。而S在發出的分組超時後,重複傳送同樣的分組。這樣就形成了死鎖。
    • 兩次握手還可能造成伺服器資源的浪費,怎麼說呢,再舉個栗子,假設今天C向S傳送了一個連線請求,並等待S的響應,S給C傳送ACK之後,就認為連線已經建立,我們知道連線建立之後是需要維護這個連線的,此時S的就需要分配資源和空間來維客棧護這個連線,那假設S給C的響應丟失了,C並未收到響應則認為連線沒有建立成功,不能正常通訊,此時S維護的連線就是一個失敗的連線,不能成功通訊,那假設今天由100萬個客戶端向S這個伺服器傳送連線請求,結果都沒有收到響應,此時S就維護了100萬個無用的連線,浪費伺服器的資源

    為什麼是三次握手,四次揮手

    答:因為當Server端收到Client端的SYN連線請求報文後,可以直接傳送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。

    但是關閉連線時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,“你發的FIN報文我收到了”。

    只有等到Server端所有的報文都發送完了,所有的資料也處理完了之後,Server端才能傳送FIN報文表示自己能夠斷開連線,因此不能一起傳送。故需要四步握手。

    如果已經建立了連線,但是客戶端突然出現故障了怎麼辦?

    答:TCP連線是有一個保活計時器,顯然,客戶端如果出現故障,伺服器不能一直等下去,白白浪費資源。

    伺服器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設定為2小時,若兩小時還沒有收到客戶端的任何資料,伺服器就會發送一個探測報文段,以後每隔75秒鐘傳送一次。

    若一連發送10個探測報文仍然沒反應,伺服器就認為客戶端出了故障,接著就關閉連線。

    為什麼會有TIME_WAIT狀態

    現在做一個測試,首先啟動server,然後啟動client,然後用Ctrl-C使server終止,這時馬上再執行server,結果是:

    計算機網路傳輸協議TCP三次握手與四次揮手原理

    這是因為,雖然server的應用程式終止了,但TCP協議層的連線並沒有完全斷開,因此不能再次監 聽同樣的server埠.我們用netstat命令檢視一下:

    理解TIME_WAIT

    • TCP協議規定,主動關閉連線的一方要處於TIME_ WAIT狀態,等待兩個MSL(maximum segment lifetime)的時間後才能回到CLOSED狀態.
    • 我們使用Ctrl-C終止了server,所以server是主動關閉連線的一方,在TIME_WAIT期間仍然不能再次監聽同樣的server埠;
    • MSL在RFC1122中規定為兩分鐘,但是各作業系統的實現不同,在Centos7上預設配置的值是60s;
    • 可以通過 cat /proc/sys/net/ipv4/tcp_fin_timeout 檢視msl的值

    我們來想一想,為什麼TIME_WAIT的時間是2MSL

    MSL是TCP報文的最大生存時間,因此TIME_WAIT持續存在2MSL的話就能保證在兩個傳輸方向上的尚未被接收或遲到的報文段都已經消失(否則伺服器立刻重啟,可能會收到來自上一個程序的遲到的資料,但是這種資料很可能是錯誤的);

    同時也是在理論上保證最後一個報文可靠到達(假設最後一個ACK丟失,那麼伺服器會再重發一個FIN. 這時雖然客戶端的程序不在了,但是TCP連線還在,仍然可以重發LAST_ACK);

    解決TIME_WAIT狀態引起的bind失敗的方法

    • 在server的TCP連線沒有完全斷開之前不允許重新監聽,某些情況下可能是不合理的
    • 伺服器需要處理非常大量的客戶端的連線(每個連線的生存時間可能很短,但是每秒都有很大數量的客戶端來請求).
    • 這個時候如果由伺服器端主動關閉連線(比如某些客戶端不活躍,就需要被伺服器端主動清理掉),就會產生大量TIME_WAIT連線.
    • 由於我們的請求量很大,就可能導致TIME_WAIT的連線數很多,每個連線都會佔用一個通訊五元組(源ip,源埠,目的ip,目的埠,協議). 其中伺服器的ip和埠和協議是固定的. 如www.cppcns.com果新來的客戶端連線的ip和埠號和TIME_WAIT佔用的連結重複了,就會出現問題.
    • 使用setsockopt() 設定socket描述符的 選項SO_REUSEADDR為1,表示允許建立埠號相同但IP地址不同的多個socket描述符

    setsockopt

    • 加上了setsockopt之後,ctrl+c終止伺服器之後也可以馬上啟動伺服器

    setsocket

    以上就是計算機網路傳輸協議TCP三次握手與四次揮手原理的詳細內容,更多關於TCP三次握手與四次揮手的資料請關注我們www.cppcns.com其它相關文章!