TCP 協議 ---- "三次握手,四次揮手"

一、TCP 協議

    1、概念:TCP協議,即 傳輸控制協議。它是面向連接、可靠的傳輸層協議。

    2、特點:工作在 傳輸層;每一條TCP連接只能是點對點的;面向連接、可靠性;提供全雙工通信;基於字節流。

    3、TCP 數據報格式:   TCP 基於 字節流

        wKiom1c4e9yBm-D-AACGm3I7tuM154.jpg

  源端口號、目的端口號:各佔 2字節(16位) 序號:4字節 範圍[0,2^32 - 1],使用mod/(2^32)計算

  URG:緊急  1 緊急指針字段有效            ACK:確認  1 確認字段有效

  PSH:推送  兩應用進行交互,一方希望發送命令後就立即收到對方響應

  RST:復位 (重建位/重置位) 1 TCP連接出現嚴重錯誤,須釋放連接,再重新建立連接

  SYN:同步  1 連接請求/連接接受報文

  FIN:終止  1 數據已發送完畢,釋放連接

  窗口字段:現在允許對方發送的數據量

  檢驗和:2字節  範圍[首部 + 數據]

  緊急指針:2字節 (僅在URG=1時有意義)指出緊急數據的末尾在文段中的位置

  MSS:最大報文長度 [TCP報文長度 - TCP首部長度]

  選項:長度可變(最長40字節) 若無選項,則 TCP首部長度 20字節


    3、連接: 套接字socket = (IP地址 :端口號)



 

            wKioL1c4fNbj3ZucAACQBZUTSCI670.jpg



I. 三次握手:    建立連接的過程:

    1.客戶端發出段1,SYN位表示連接請求。

    序號是1000,這個序號在網絡通訊中用作臨時的地址,每發一個數據字節,這個序號要加1,這樣在接收端可以根據序號排出數據包的正確順序,也可以發現丟包的情況。另外,規定SYN位和FIN位也要佔一個序號,這次雖然沒發數據,但是由於發了SYN位,因此下次再發送應該用序號1001。mss表示最大段尺寸,如果一個段太大,封裝成幀後超過了鏈路層的最大幀長度,就必須在IP 層分片,爲了避免這種情況,客戶端聲明自己的最大段尺寸,建議服務器端發來的段不要超過這個長度。 

    2.服務器發出段2,也帶有SYN位,同時置ACK位表示確認,確認序號是1001,表示“我接收到序號1000及其以前所有的段,請你下次發送序號爲1001的段”,也就是應答了客戶端的連接請求,同時也給客戶端發出一個連接請求,同時聲明最大尺寸爲1024。 

    3.客戶端發出段3,對服務器的連接請求進行應答,確認序號是8001。


II. 四次握手:   關閉連接的過程:

    1. 客戶端發出段7, FIN位:關閉連接的請求。

       2. 服務器發出段8, 應答客戶端的關閉連接請求。
       3. 服務器發出段9, 其中也包含FIN位,向客戶端發送關閉連接請求。

       4. 客戶端發出段10, 應答服務器的關閉連接請求。

注:正在關閉或者TIME_WAIT狀態的tcp連接,不能傳輸http請求和響應。


III.TIME_WAIT

   通信雙方建立TCP連接後,主動關閉連接的一方就會進入TIME_WAIT狀態。

客戶端主動關閉連接時,會發送最後一個ack後,然後會進入TIME_WAIT狀態,再停留2個MSL時間(後有MSL的解釋),進入CLOSED狀態。

    MSL就是maximum segment lifetime(最大分節生命期),這是一個IP數據包能在互聯網上生存的最長時間,超過這個時間IP數據包將在網絡中消失 。MSL在RFC 1122上建議是2分鐘,而源自berkeley的TCP實現傳統上使用30秒。

TIME_WAIT狀態維持時間: 兩個MSL時間長度,也就是在1-4分鐘。Windows操作系統就是4分鐘。

    

    1)客戶端主動關閉連接

[ 進入TIME_WAIT狀態的一般情況下是客戶端 ]

    大多數服務器端一般執行被動關閉,服務器不會進入TIME_WAIT狀態。

    當在服務器端關閉某個服務再重新啓動時,服務器是會進入TIME_WAIT狀態的。

舉例:

1.客戶端連接服務器的80服務,這時客戶端會啓用一個本地的端口訪問服務器的80,訪問完成後關閉此連接,立刻再次訪問服務器的

80,這時客戶端會啓用另一個本地的端口,而不是剛纔使用的那個本地端口。原因就是剛纔的那個連接還處於TIME_WAIT狀態。

2.客戶端連接服務器的80服務,這時服務器關閉80端口,立即再次重啓80端口的服務,這時可能不會成功啓動,原因也是服務器的連接還處於TIME_WAIT狀態。

 

服務端提供服務時,一般監聽一個端口就夠了。例如Apach監聽80端口。

客戶端則是使用一個本地的空閒端口(大於1024),與服務端的Apache的80端口建立連接。

當通信時使用短連接,並由客戶端主動關閉連接時,主動關閉連接的客戶端會產生TIME_WAIT狀態的連接,一個TIME_WAIT狀態的連接就佔用了一個本地端口。這樣在TIME_WAIT狀態結束之前,本地最多就能承受6萬個TIME_WAIT狀態的連接,就無端口可用了。

客戶端與服務端進行短連接的TCP通信,如果在同一臺機器上進行壓力測試模擬上萬的客戶請求,並且循環與服務端進行短連接通信,那麼這臺機器將產生4000個左右的TIME_WAIT socket,後續的短連接就會產生address already in use : connect的異常。

 

關閉的時候使用RST的方式,不進入 TIME_WAIT狀態,是否可行?

 

    2)服務端主動關閉連接

    [ 大多數服務器端一般執行被動關閉,服務器不會進入TIME_WAIT狀態 ]

    服務端提供在服務時,一般監聽一個端口就夠了。例如Apach監聽80端口。

    客戶端則是使用一個本地的空閒端口(大於1024),與服務端的Apache的80端口建立連接。

    當通信時使用短連接,並由服務端主動關閉連接時,主動關閉連接的服務端會產生TIME_WAIT狀態的連接。

    由於都連接到服務端80端口,服務端的TIME_WAIT狀態的連接會有很多個。 

服務器端爲了解決這個TIME_WAIT問題,可選擇的方式有三種:

     保證由客戶端主動發起關閉(即做爲B端)

     關閉的時候使用RST的方式

     對處於TIME_WAIT狀態的TCP允許重用

 3)使用情形    

    wKioL1ddCTHhj4SYAAAp5qgJudQ947.jpg


返回結果如下:

    LAST_ACK 14

    SYN_RECV 348

    ESTABLISHED 70

    FIN_WAIT1 229

    FIN_WAIT2 30

    CLOSING 33

    TIME_WAIT 18122

 

對上述結果的解釋:

    CLOSED:無連接是活動的或正在進行

    LISTEN:服務器在等待進入呼叫

    SYN_RECV:一個連接請求已經到達,等待確認

    SYN_SENT:應用已經開始,打開一個連接

    ESTABLISHED:正常數據傳輸狀態

    FIN_WAIT1:應用說它已經完成

    FIN_WAIT2:另一邊已同意釋放

    ITMED_WAIT:等待所有分組死掉

    CLOSING:兩邊同時嘗試關閉

    TIME_WAIT:另一邊已初始化一個釋放

    LAST_ACK:等待所有分組死掉


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章