網絡協(xié)議(十)-傳輸層(連接管理)

以下內容來自于小碼哥"網絡協(xié)議從入門到底層原理"

image.png
image.png
分析一下自己抓包的結果
image.png

上圖是一個典型的三次握手
我們來分析一下第一次握手

  • 第一次握手


    image.png

第一次握手的數(shù)據(jù)部分的長度是0個字節(jié), TCP首部占44個字節(jié), 其中固定部分長度是20個字節(jié), 選項部分長度是24個字節(jié)

TCP首部存儲的是Sequenceraw值,而不是相對值 見下圖

image.png

我們把這個值稱為s1, 這個s1記錄的是客戶端->服務器發(fā)送的每一個segment的第一個字節(jié)的編號

  • 我們來分析一下第二次握手


    image.png
  • 我們來分析一下第三次握手


    image.png

三次握手后, TCP連接就成功建立
建立了發(fā)數(shù)據(jù)的通道, 這是一個全雙工的通道, 即客戶端也可以發(fā)給服務器, 服務器也可以發(fā)給客戶端

  • 然后客戶端發(fā)給服務器HTTP請求

    image.png

  • 服務端收到客戶端發(fā)過來的HTTP請求之后, 就會發(fā)給客戶端一個收到的ACK響應

    image.png

  • 然后服務端就開始發(fā)數(shù)據(jù)給客戶端了


    image.png

看上圖可以知道: 上圖的ACK全部是719, 這是為什么呢? 719ACK的相對值, 即718 + 1 = 719, 718是客戶端發(fā)給服務器的HTTP請求的長度, 即TCP的數(shù)據(jù)部分, 所以ACKraw值應該是期望客戶端發(fā)給服務器的下一個包的第一個字節(jié)的值, 即s1 + b1 + 1, 因為在這個過程中, 并沒有收到客戶端發(fā)給服務器的任何數(shù)據(jù)包, 那么這個值就始終是s1 + b1 + 1, 相對值就始終是719.

但是會變化的是序號seq值, seq值是上一個包的seq值, 加上長度Len生成的, 比如上圖中最后一個包的seq4771, 而4771 = 4755 + 16, 4755就是上一個服務器發(fā)給客戶端包的seq值. 如果把上圖這7個包的長度分別記為k1, k2, k3, k4, k5, k6, k7的話, 那么最后一個包的seq相對值就是1 + k1 + k2 + k3 + k4 + k5 + k6, raw值就是s2 + 1 + k1 + k2 + k3 + k4 + k5 + k6,

讓我們看看是不是這樣, 我們點開最后一個包:

image.png
image.png

s2的值果然就是這樣

  • 接下來就是客戶端對服務端的ACK回應, 告訴客戶端, 我收到包了:
image.png

注意看最后一個包的ACK6223, 這就是服務器發(fā)給客戶端的最后一個包的seq + Len:

image.png

  • 就這樣反反復復, 直到服務端這邊已經發(fā)完了全部數(shù)據(jù), 那么就會給客戶端返回一個200:
    image.png

從上面的圖可以看到, 客戶端這邊發(fā)的好多包的seq都為719, 這是因為客戶端發(fā)的包都只是一個ACK回應, 表示: 哦, 我收到了, 這樣的包的長度Len都為0, 所以seq都為s1 + b1 + 1, 就是相對值為719(718 + 1), raw值為2751725119(718 + 1 + s1(2751724400))

到此, 傳輸層的三次握手就分析完了.

TCP-建立連接-狀態(tài)解讀
  • CLOSED: client處于關閉狀態(tài)
  • LISTEN: server處于監(jiān)聽狀態(tài), 等待client連接
  • SYN-RCVD: 表示server接受到了SYN報文, 當收到clientACK報文后, 它會進入到ESTABLISHED狀態(tài)
  • SYN-SENT:表示client已發(fā)送SYN報文, 等待server的第2次握手
    image.png
TCP-建立連接-前2次握手的特點
  • SYN都設置為1

  • 數(shù)據(jù)部分的長度都為0

  • TCP頭部的長度一般是32字節(jié)
    -- 固定頭部: 20字節(jié)
    -- 選項部分: 12字節(jié)

  • 雙方會交換確認一些信息
    -- 比如MSS, 是否支持SACK, Window scale(窗口縮放系數(shù))等

TCP-建立連接-疑問
  • 為什么建立連接的時候, 要進行3次握手, 2次不行嗎?
    -- 主要目的: 防止server端一直等待, 浪費資源

  • 如果建立連接只需要2次握手, 可能會出現(xiàn)的情況
    -- 假設client發(fā)出的第一個連接請求報文段, 因為網絡延遲, 在連接釋放以后的某個時間才到達server
    -- 本來這是一個早已失效的請求, 但server收到此失效的請求后, 誤認為是client再次發(fā)出的一個新的連接請求
    -- 于是server就向client發(fā)出確認報文段, 同意建立連接
    -- 如果不采用"3次握手", 那么只要server發(fā)出確認, 新的連接就建立了
    -- 由于現(xiàn)在client并沒有真正想連接服務器的意愿, 因此不會理睬server的確認, 也不會向server發(fā)送數(shù)據(jù)
    -- 但在server卻以為新的連接已經建立, 并一直等待client發(fā)來數(shù)據(jù), 這樣, server的很多資源就白白浪費了

  • 采用"三次握手"的辦法可以防止上述現(xiàn)象發(fā)生
    -- 例如上述情況, client沒有向server的確認發(fā)出確認, server由于收不到確認, 就知道client并沒有要求建立連接

  • 3次握手失敗了, 會怎么處理?
    -- 此時server的狀態(tài)為SYN-RCVD, 若等不到clientACK, server會重新發(fā)送SYN+ACK
    -- 如果server多次重發(fā)SYN+ACK都等不到clientACK, 就會發(fā)送RST包, 強制關閉連接

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容