mbuf

www
mbuf结构体

TCP/IP详解第二卷实现主要讲的是BSD的协议栈实现。看协议栈代码,首先看的就是经典的mbuf结构了。原来觉得mbuf结构比较复杂,硬着头皮看了几天后,感觉思路上清晰了一些。于是准备写点东西把理解到的一点点先记下来,省得以后忘记了。
书上是以4.4BSDlite源代码为基础讲的。可以说是目前各个bsd发行版的基础。在此基础上,FreeBSD、NetBSD、OpenBSD做了稍许的改动。下面是lite版的mbuf声明代码:

/*
 * Mbufs are of a single size, MSIZE (machine/machparam.h), which
 * includes overhead. An mbuf may add a single "mbuf cluster" of size
 * MCLBYTES (also in machine/machparam.h), which has no additional overhead
 * and is used instead of the internal data area; this is done when
 * at least MINCLSIZE of data must be stored.
 */

#define MLEN (MSIZE - sizeof(struct m_hdr)) /* normal data len */
#define MHLEN (MLEN - sizeof(struct pkthdr)) /* data len w/pkthdr */
/* header at beginning of each mbuf: */
struct m_hdr {
        struct mbuf *mh_next; /* next buffer in chain */
        struct mbuf *mh_nextpkt; /* next chain in queue/record */
        caddr_t mh_data; /* location of data */
        int mh_len; /* amount of data in this mbuf */
        short mh_type; /* type of data in this mbuf */
        short mh_flags; /* flags; see below */
};
/* record/packet header in first mbuf of chain; valid if M_PKTHDR set */
struct pkthdr {
        struct ifnet *rcvif; /* rcv interface */
        int len; /* total packet length */
};
/* description of external storage mapped into mbuf, valid if M_EXT set */
struct m_ext {
        caddr_t ext_buf; /* start of buffer */
        void (*ext_free)(); /* free routine if not the usual */
        u_int ext_size; /* size of buffer, for ext_free */
};
struct mbuf {
        struct m_hdr m_hdr;
        union {
                struct {
                        struct pkthdr MH_pkthdr; /* M_PKTHDR set */
                        union {
                                struct m_ext MH_ext; /* M_EXT set */
                                char MH_databuf[MHLEN];
                        } MH_dat;
                } MH;
                char M_databuf[MLEN]; /* !M_PKTHDR, !M_EXT */
        } M_dat;
};

/* mbuf flags */
#define M_EXT           0x0001  /* has associated external storage */
#define M_PKTHDR        0x0002  /* start of record */
#define M_EOR           0x0004  /* end of record */


可以看到mbuf大体由两部分组成,m_hdr和M_dat。
M_dat是个联合体,使用其中哪个成员是由m_hdr.mh_flags来决定的。
  1. 如果mh_flags里没有M_EXT与M_PKTHDR,则表面此mbuf完全是用来存放数据的。总共可以存放MLEN字节的数据;
  2. 如果mh_flags里有M_EXT则表面此mbuf使用外部簇来存放数据;
  3. 如果mh_flags里有M_PKTHDR,则表面此mbuf是一个记录的起始mbuf,由于MH_pkthdr占用了部分空间总共只能存放MHLEN字节的数据;
  4. 如果mh_flags里既有M_PKTHDR又有M_EXT则表面此mbuf是起始mbuf,但是使用外部簇来存放数据。

我的批注: mbuf结构的大小总是为128字节,

 

2. 指针m_next把mbuf链接在一起,把一个分组形成一条mbuf链表

 

3. 指针m_nextpkt把多个分组链接成一个mbuf链表队列。在队列中的每个分组可以是一个单独的mbuf,也可以是一个mbuf链表。每个分组的第一个mbuf包含一个分组首部。

`U8 *mbuf` 是一个指向 `U8` 类型的指针,通常用于指向一段内存缓冲区。在嵌入式系统、NFC通信、网络协议或底层数据处理中非常常见。 --- ### 类型解释 - `U8` 通常是 `typedef unsigned char U8;` 的定义,表示一个 8 位无符号整数(即一个字节)。 - `U8 *mbuf` 表示一个指向 `U8` 类型的指针,常用于操作二进制数据缓冲区。 --- ### 常见用途 1. **接收数据缓冲区** `mbuf` 可能指向从 NFC 标签、网络、串口、文件等读取的原始二进制数据。 2. **数据复制与处理** 例如: ```c memcpy(card_num, mbuf, mlen); // 将 mbuf 中的 mlen 字节复制到 card_num ``` 3. **动态内存分配** ```c mbuf = (U8 *)malloc(32); // 分配 32 字节的缓冲区 if (mbuf == NULL) { // 错误处理 } ``` 4. **函数参数传递** 常用于函数间传递原始数据块: ```c void process_data(U8 *mbuf, size_t len); ``` --- ### 示例代码 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> typedef unsigned char U8; int main() { U8 card_num[32] = {0}; U8 *mbuf; size_t mlen = 4; mbuf = (U8 *)malloc(mlen); if (mbuf == NULL) { printf("Memory allocation failed\n"); return -1; } mbuf[0] = 0xBD; mbuf[1] = 0x9D; mbuf[2] = 0xF0; mbuf[3] = 0x65; memcpy(card_num, mbuf, mlen); // 打印数据 for (int i = 0; i < mlen; i++) { printf("card_num[%d] = 0x%02X\n", i, card_num[i]); } free(mbuf); return 0; } ``` --- ### 注意事项 - **内存安全**:使用 `malloc` 后必须检查是否分配成功。 - **长度控制**:使用 `memcpy` 时必须确保 `mlen <= 目标缓冲区大小`。 - **释放内存**:使用完 `malloc` 分配的内存后,必须调用 `free(mbuf)` 避免内存泄漏。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值