TCP-IP详解 卷2:实现之mbuf存储器缓存

mbuf的种类:       

        mbuf,全称为"memory buffer",主要用于保存进程和网络接口间互相传递的用户数据,也用于保存源与目标地址,插口选项等。

       mbuf 依据m_flags中填写的不同标志M_PKTHDR和M_EXT而不同。mbuf主要有四种:

1):m_flags 为 0 ,mbuf只包含数据。mbuf中有108字节的数据空间,指针m_data指向108字节缓存的某一位置。

2):m_flags 为 M_PKTHDR,这表示一个分组首部,描述一个分组数据的第一个mbuf。

3):这种mbuf不包含分组首部(没有设置K_PKTHDR),但包含超过208字节的数据,这时用到了一个外部缓存cluster(需要设置M_EXT)

4):最后一个包含一个分组首部,包含超过208字节的数据

这四种mbuf的区别如下图所示:

TCP-IP详解 卷2:实现之mbuf存储器缓存_第1张图片

mbuf的结构:


/* mbuf的头部信息 */
struct m_hdr {
       struct       mbuf *mh_next;             /* 指向链中下一个mbuf的指针 */
       struct       mbuf *mh_nextpkt;     /* 指向下一个链的指针 */
       int        mh_len;                     /* mbuf中数据的长度(不包括头部) */
       char    *mh_data;                     /* 指向数据区的指针 */
       short       mh_type;                /* mbuf的数据类型,如MT_DATA*/
       short       mh_flags;                      /* mbuf标识,具体定义见下 */
};




/* mbuf标识*/
#define       M_EXT          0x0001    /* has associated external storage */
#define       M_PKTHDR     0x0002    /* start of record */
#define       M_EOR          0x0004    /* end of record */
 
struct      pkthdr {
       int        len;               /* 整个mbuf链表包含数据的总长度,在链表的第一个mbuf中维护一个带有总长度的分组首部的原因是,当需要总长度时可以避免查看所有mbuf中的mh_len来求和*/
       struct       ifnet *rcvif;        /* 指向接收分组的接收接口结构的指针*/
};


struct m_ext{

caddr_t ext_buf; // start of buffer

void (*ext_free)(); //free routine if not the usual

u_int ext_size;

};
 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;
};



   关于m_flags 的取值,前面我们已经议论了M_EXT 和M_PKTHDR.这里m_flags 的取值有五种



你可能感兴趣的:(TCPIP详解实现,m_bufs)