您好,登錄后才能下訂單哦!
這篇文章主要講解了“Lwip數(shù)據(jù)包的管理方法”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Lwip數(shù)據(jù)包的管理方法”吧!
LWIP是TCP/IP協(xié)議棧的一種具體實(shí)現(xiàn),本質(zhì)就是對(duì)數(shù)據(jù)包的處理,在LWIP中使用一個(gè)被稱為pbuf的結(jié)構(gòu)管理數(shù)據(jù)包,LWIP源碼中的pbuf.c和pbuf.h這兩個(gè)文件就是關(guān)于pbuf的,pbuf結(jié)構(gòu)如下:
在pbuf.h文件中
下面是翻譯版
struct pbuf { struct pbuf *next; //構(gòu)成鏈表的時(shí)候指向下一個(gè)pbuf void *payload; //指向數(shù)據(jù)緩沖區(qū) u16_t tot_len; //pbuf鏈表中所有pbuf的數(shù)據(jù)長(zhǎng)度 u16_t len; //當(dāng)前bpuf中的數(shù)據(jù)長(zhǎng)度 u8_t type; //pbuf類型 u8_t flags; //狀態(tài) u16_t ref; //用來記錄當(dāng)前pbuf被引用的次數(shù) };
說一下tot_len的講解
大家最好理解一下英文的意思,我說完中文,再回頭看一下英文。
下面我們看一下type
從這里可是使用編譯器跳過去
也就是pbuf_type的類型有
typedef enum { PBUF_RAM, //pbuf數(shù)據(jù)緊跟著pbuf的結(jié)構(gòu)存儲(chǔ),數(shù)據(jù)存儲(chǔ)在ram中 PBUF_ROM, //pbuf數(shù)據(jù)存儲(chǔ)在rom中 PBUF_REF, //pbuf數(shù)據(jù)存儲(chǔ)在ram中,但是與pbuf結(jié)構(gòu)的位置無關(guān) PBUF_POOL //pbuf結(jié)構(gòu)和其數(shù)據(jù)存儲(chǔ)在同一個(gè)內(nèi)存池中 } pbuf_type;
分別講一下這四種類型
PBUF_RAM類型的pbuf空間是從LWIP的內(nèi)存堆中申請(qǐng)得到的,協(xié)議棧和應(yīng)用程序中的待發(fā)送數(shù)據(jù)就是采用的這種方法,pbuf的申請(qǐng)是在pbuf_alloc()中進(jìn)行的,PBUF_RAM類型的申請(qǐng)代碼如下:
在pbuf.c文件中pbuf_alloc函數(shù)
看到mem_malloc()函數(shù),知道是從內(nèi)存堆里申請(qǐng)的內(nèi)存
申請(qǐng)的大小是:pbuf的大小+ 實(shí)際申請(qǐng)的大小
offset是一個(gè)偏移,這個(gè)offset里面用來存儲(chǔ)一些首部字段,如TCP報(bào)文首部,IP首部等等。
最終申請(qǐng)出來的PBUF_RAM類型的pbuf結(jié)構(gòu)是
下圖1部分的就是pbuf結(jié)構(gòu)部分
2部分是offset部分
PBUF_POOL類型的pbuf空間是從LWIP的內(nèi)存池中申請(qǐng)得到的,因?yàn)槭菑膬?nèi)存池中申請(qǐng)的,所以這種類型的pbuf分配時(shí)間極短,在網(wǎng)卡接收數(shù)據(jù)包時(shí),我們使用這種方式:
在pbuf.c文件中pbuf_alloc函數(shù)
既然PBUF_POOL類型是在內(nèi)存池中申請(qǐng)的,那么就必須得有對(duì)應(yīng)的POOL類型,在LWIP初始化的時(shí)候就會(huì)自動(dòng)的兩類與pbuf相關(guān)的POOL:MEMP_PBUF和MEMP_PBUF_POOL(在memp_std.h中),其中MEMP_PBUF是用于PBUF_REF和PBUF_ROM這兩類的,MEMP_PBUF_POOL是用于PBUF_POOL類型的。
事實(shí)上應(yīng)用程序發(fā)送和接收的數(shù)據(jù)量可能很大,但是內(nèi)存池類型的內(nèi)存分配每次分配到的大小是固定的,因此可能會(huì)需要進(jìn)行多次分配,最終的分配成功的PBUF_POOL類型的pbuf如下圖:
注意看,上圖中只有第一個(gè)pbuf有offset,這是因?yàn)檫@都是一個(gè)數(shù)據(jù)包的,因此只需要一個(gè)offset來存儲(chǔ)有關(guān)數(shù)據(jù)包的信息,其他的pbuf就不需要了!這部分也是在代碼中體現(xiàn)過的
第一個(gè)pbuf的payload
后續(xù)的pbuf的payload
PBUF_ROM和PBUF_REF類型的pbuf空間也是從LWIP的內(nèi)存池中申請(qǐng)得到的,分配方法都一樣的,他們使用內(nèi)存池MEMP_PBUF,這兩種類型申請(qǐng)的是指pbuf結(jié)構(gòu)體的內(nèi)存空間,并不包含數(shù)據(jù)空間,分配過程如下:
PBUF_ROM和PBUF_REF并沒有給數(shù)據(jù)空間申請(qǐng)內(nèi)存,那么他們的數(shù)據(jù)空間在哪里呢?這兩個(gè)的數(shù)據(jù)空間可以應(yīng)用其他地方的內(nèi)存,不同之處在于PBUF_ROM的數(shù)據(jù)空間在ROM中,PBUF_REF的數(shù)據(jù)空間在RAM中。這兩種類型的pbuf最終如下:
實(shí)際的數(shù)據(jù)包可能會(huì)同時(shí)使用多種類型的pbuf,如下圖:
pbuf的申請(qǐng)和釋放通過函數(shù)pbuf_alloc()和pbuf_free()來完成,pbuf_alloc()函數(shù)和pbuf_free()函數(shù)原型如下:
pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) pbuf_free(struct pbuf *p)
pbuf_alloc()函數(shù)有兩個(gè)重要的參數(shù):layer和type,layer決定是協(xié)議棧的哪一層申請(qǐng)的,type決定申請(qǐng)的pbuf類型,layer決定了pbuf中的offset,也就是pbuf數(shù)據(jù)區(qū)中衛(wèi)協(xié)議預(yù)留的首部空間,pbuf.h文件定義了一個(gè)枚舉類型pbuf_layer來描述LWIP中的層,如下:
typedef enum { PBUF_TRANSPORT, PBUF_IP, PBUF_LINK, PBUF_RAW } pbuf_layer;
感謝各位的閱讀,以上就是“Lwip數(shù)據(jù)包的管理方法”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Lwip數(shù)據(jù)包的管理方法這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。