回覆列表
  • 1 # 使用者7751309742223

    udp socket不存在粘包問題, 但是存在亂序, 丟包, 重複到達的情況

    假設在沒丟包的情況下

    又假設你的應用層緩衝區和想要取的位元組足夠大(至少長度要大於你要取出來的udp包)

    udp的包可以完整乾淨的取出來, 包與包之間資料彼此獨立(不粘包), 包內部資料不會亂序

    就是說你傳送端傳送了兩個包, 一個ABC三個位元組, 另外一個是DEF三個位元組, 只要沒丟包沒重複到達的情況下, 接收端收到的兩個包肯定是一個[ABC], 另外一個是[DEF]

    但是tcp的socket就有可能粘包(粘包是常態)

    畢竟TCP是"流協議"(stream), 是"無記錄邊界(位元組流)"的協議

    仔細理解"流"的概念, 看看江河湖海里面的水流甚至你家水龍頭裡的自來水

    裡面的水流(位元組)是不是連續的, 假設只有一個出口(peer)的前提下, 源源不斷的位元組流流出來, 無法斷定這一段流裡面是包含了多個數據包, 還是一個恰好完整的包, 還是隻包含了半個包 (另外的半個包得繼續等接下來的位元組流.)

    並且往往想要取到後面的水流, 你得把這之前的水流都取出來才可以(有序). 常規操作下不能直接取某一段(尤其是後面)的水流.

    傳送端同樣發兩個包, 一個ABC三個位元組, 另外一個是DEF三個位元組

    這裡假設接收端每次核心緩衝區有資料就讀取全部資料, 且應用層緩衝區足夠大

    那麼接收端

    可能返回2次, [ABC][DEF], 這種情況就如同傳送端傳送的情況一樣

    可能返回3次, [AB][CD][EF]

    也可能返回一次[ABCDEF], 比如傳送的時候網路突然不太好, 一直在積壓, 突然網路暢通了一次都發出去了

    甚至可能返回6次, [A], [B], [C], [D], [E], [F]網路斷斷續續

    這就是為啥大部分tcp都要自己搞tlv(往往定義個定長的包頭, 包頭裡面帶著變長的包體長度)來定義一個應用層資料包, 這樣可以從源源不斷的流中一個接一個區分(擷取)出多個具體的資料包

  • 中秋節和大豐收的關聯?
  • 針管筆用來做漫畫勾線好用嗎?