LWIP_簡記(5.數據包管理)

LWIP一句話記住就行:
一項工程,兩份配置,三種內存分配,四套操作API,五步初始化,六個"數據流",七個數據結構
-------------------------------------------

先整鏈接:https://blog.csdn.net/XieWinter/article/details/99829412
這篇博文講的特別清楚詳細.

前言

再來自我總結:
lwip說到底也就是TCPIP協議,那本質就是數據的傳遞.
這裏必須要強調一點兒:數據包和數據是兩個完全不同的概念,前者包含後者.(雖然有點兒傻,但是真的要時刻謹記),理解pbuf和buffer.
因爲用戶只關係數據,但是在網絡數據包中對於程序員更應該關心數據外的東東,比如包頭(類型,大小,標記,檢驗和...)

PBUF

好了回到lwip上來,
在lwip中pbuf 就是一個描述協議棧中數據包的數據結構,LwIP 中在pbuf.c 和pubf.h 實現了協議棧數據包管理的所有函數與數據結構。
不失一般性我們進行提綱挈領的總結:
1.PBUF結構:

185 /** Main packet buffer struct */
186 struct pbuf {
187   /** next pbuf in singly linked pbuf chain */
188   struct pbuf *next;
189  //由此可以看出是個單向鏈表
190   /** pointer to the actual data in the buffer */
191   void *payload;
192  //指向真實數據(buffer慣用來表示數據)的首地址
193   /**
194    * total length of this buffer and all next buffers in chain
195    * belonging to the same packet.
196    *
197    * For non-queue packet chains this is the invariant:
198    * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
199    */
200   u16_t tot_len;
201  //等於當前len+下一個tot_len
202   /** length of this buffer */
203   u16_t len;
204  
205   /** a bit field indicating pbuf type and allocation sources
206       (see PBUF_TYPE_FLAG_*, PBUF_ALLOC_FLAG_* and PBUF_TYPE_ALLOC_SRC_MASK)
207     */
208   u8_t type_internal;
209  
210   /** misc flags */
211   u8_t flags;
212  
213   /**
214    * the reference count always equals the number of pointers
215    * that refer to this pbuf. This can be pointers from an application,
216    * the stack itself, or pbuf->next pointers from a chain.
217    */
218   LWIP_PBUF_REF_T ref;
219   //被引用次數                                                                                                                                                                 
220   /** For incoming packets, this contains the input netif's index */
221   u8_t if_idx;
222  //用於記錄傳入的數據包中輸入netif 的索引,也就是netif 中num 字段
223 };

看代碼可能沒有上圖來的刺激:具體字段的解釋上面註釋已經說的很清楚了.
在這裏插入圖片描述
2.PBUF tot_len字段
一定要注意計算方式:
tot_len = len + Next_tot_len.
由此可以看出只有第一個pbuf結構的tot_len表示了整個數據包的大小.

3.PBUF類型


/**
 * @ingroup pbuf
 * Enumeration of pbuf types
 */
typedef enum {
  /** pbuf data is stored in RAM, used for TX mostly, struct pbuf and its payload
      are allocated in one piece of contiguous memory (so the first payload byte
      can be calculated from struct pbuf).
      pbuf_alloc() allocates PBUF_RAM pbufs as unchained pbufs (although that might
      change in future versions).
      This should be used for all OUTGOING packets (TX).*/
  PBUF_RAM = (PBUF_ALLOC_FLAG_DATA_CONTIGUOUS | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP),
  /** pbuf data is stored in ROM, i.e. struct pbuf and its payload are located in
      totally different memory areas. Since it points to ROM, payload does not
      have to be copied when queued for transmission. */
  PBUF_ROM = PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF,
  /** pbuf comes from the pbuf pool. Much like PBUF_ROM but payload might change
      so it has to be duplicated when queued before transmitting, depending on
      who has a 'ref' to it. */
  PBUF_REF = (PBUF_TYPE_FLAG_DATA_VOLATILE | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF),
  /** pbuf payload refers to RAM. This one comes from a pool and should be used
      for RX. Payload can be chained (scatter-gather RX) but like PBUF_RAM, struct
      pbuf and its payload are allocated in one piece of contiguous memory (so
      the first payload byte can be calculated from struct pbuf).
      Don't use this for TX, if the pool becomes empty e.g. because of TCP queuing,
      you are unable to receive TCP acks! */
  PBUF_POOL = (PBUF_ALLOC_FLAG_RX | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL)
} pbuf_type;

具體類型之間的差異就不多說了,前面給的鏈接講的很清楚了.

4.PBUF操作


struct pbuf *
pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
//留意三個參數:數據包在那一層被申請,長度,類型

理解一下第一個參數:
因爲pbuf結構貫穿整個tcpip協議層,我們知道每一層的數據包頭部是不一樣的.所以需要預留協議首部空間.

pbuf_free()

這裏需要提出來的就是ref字段了.

1.申請pbuf時ref字段初始化爲1.
2.釋放時先將ref減1,只有ref減到爲0,才能被釋放.
3.只有pbuf首節點才能被釋放.

關於pbuf的具體使用,比如數據*payload是怎樣給到buffer的,我們後面遇到了再細看.
-------------------------------------------
這期就到這裏了,LWIP想怎麼玩就怎麼玩,我們下期再見.

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