“mBlk-clBlk-cluster“三元组结构设计原理

	数据包在网络协议栈中从上向下流动时,需要在数据的首部和尾部为其增加相应的包头和包尾。例如在TCP/IP协议栈中,数据从应用层向下传输的过程中,需要为其封装TCP头部、IP头部等,使得接收端能根据各层的报头来正确的接收数据。这就要求存储数据的缓冲区是可变长的,而同时如果数据是通过拷贝在协议层之间传输时,大量的拷贝会极大的影响性能。
	因此在VxWorks中,网络协议栈采用了MBlk-ClBlk-Cluster三元组的结构来存储数据。

1)在为数据包封装头部时,申请一个新的mBlk来存放待封装的报头,并将其链接到mBlk链的头部,这样就不需要拷贝了。
2)将真正待传输的上层数据存放在Cluster中,MBlk通过操作Cluster来引用数据。这样数据在协议层之间传输时,只需要修改MBlk的指针即可,不用真正的拷贝数据。
使用三元组的结构来存储网络协议栈中的数据,可以极大的提升系统性能。
1、存储池netPool
存储池netPool与内存池类似,在初始化的时候,就先根据配置构造好一定数量的mBlk、ClBlk和Cluster。然后在需要用到时,从存储池中取出相应的结构,并将其组合在一起即可。
存储池初始化后的示意图如下:
在这里插入图片描述
由上图可知,一个存储池又可分为一个mBlk池、一个ClBlk池和多个Cluster池,其中不同的Cluster池中存放着大小不同的Cluster,Cluster的大小默认可以为64、128、256、512、1024、2048这几种。不同Cluster池中Cluster的个数也不相同。
在使用时,根据需要选择大小最合适的Cluster。
netPool的结构体如下所示:

struct netPool				/* NET_POOL */
    {
    M_BLK_ID	pmBlkHead;		/* head of mBlks */
    CL_BLK_ID	pClBlkHead;		/* head of cluster Blocks */
    int		mBlkCnt;		/* number of mblks */
    int		mBlkFree;		/* number of free mblks */
    int		clMask;			/* cluster availability mask */
    int		clLg2Max;		/* cluster log2 maximum size */
    int		clSizeMax;		/* maximum cluster size */
    int		clLg2Min;		/* cluster log2 minimum size */
    int		clSizeMin;		/* minimum cluster size */
    CL_POOL * 	clTbl [CL_TBL_SIZE];	/* pool table */
    M_STAT *	pPoolStat;		/* pool statistics */
    POOL_FUNC *	pFuncTbl;		/* ptr to function ptr table */
    };

每个mBlk、ClBlk、Cluster子池中的元素都通过一个next指针形成链表,而netPool则需要保存链表头部信息即可。
上述结构体中,pmBlkHead指向mBlk池的头部,pClBlkHead指向ClBlk池的头部,clTbl[CL_TBL_SIZE]则保存了不同大小的Cluster形成的各个Cluster池的信息。
这样就可以通过netPool结构来管理mBlk-ClBlk-Cluster三元组结构了。

2、mBlk
mBlk的结构体如下:

typedef struct mBlk
    {
    M_BLK_HDR 	mBlkHdr; 		/* mBlk相关信息 */
    M_PKT_HDR	mBlkPktHdr;		/* 与接收端口相关的信息 */
    CL_BLK *	pClBlk;			/* 指向ClBlk */
    } M_BLK;

typedef struct mHdr
    {
    struct mBlk *	mNext;		/* next buffer in chain ,形成横向链表*/
    struct mBlk *	mNextPkt;	/* next chain in queue/record ,形成纵向链表*/
    char *		mData;		/* location of data ,指向数据区*/
    int			mLen;		/* amount of data in this mBlk */
    UCHAR		mType;		/* type of data in this mBlk */
    UCHAR		mFlags;		/* flags; see below */
    USHORT		reserved; 
    } M_BLK_HDR;

mBlk结构体通过mBlkHdr结构体中的mNext和mNextPkt两个指针,形成纵向和横向两个链表,如下所示:
在这里插入图片描述
每一条横向的mBlk链为一个完整的数据包,纵向mBlk链则将多个数据包链接在一起,形成一个数据包链表。

3、clBlk

typedef struct clBlk
    {
    CL_BLK_LIST 	clNode;		/* union of next clBlk, buffer ptr */
    int		clSize;		/* cluster size */
    int			clRefCnt;	/* reference count of the cluster */
    FUNCPTR		pClFreeRtn;	/* pointer to cluster free routine */
    int			clFreeArg1;	/* free routine arg 1 */
    int			clFreeArg2;	/* free routine arg 2 */
    int			clFreeArg3;	/* free routine arg 3 */
    struct netPool *	pNetPool;	/* pointer to the netPool */
    } CL_BLK;

由上可知,clNode是一个联合体,当clBlk空闲时,指向下一个clBlk,即在ClBlk池中形成链表。而当clBlk被使用时,则指向具体的数据区,一般为一个Cluster。
通过clRefCnt完成引用计数,当计数为0时,则将其归还到存储池中。

4、Cluster

当Cluster空闲时,其首部四个字节指向下一个Cluster,从而以链表形式形成一个Cluster池。而当Cluster被使用时,则为具体的数据区。
通过以上的分析可知,一个基本的三元组结构示意图如下:
在这里插入图片描述
多个mBlk则通过mBlk.mBlkHdr中的mNext和mNextPkt指针形成横向和纵向的链表,来构造实际的数据包。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值