头文件
#ifndef _M_H
#define _M_H
#define MLEN 1024
#define MAXSIZE 20
#define BUFSIZE 30
typedef struct m_head {
struct mbuf *mh_next; /*指向当前数据链表的下一个mbuf*/
struct mbuf *mh_nextpkt; /*下一个数据链表*/
int mh_len; /*数据长度*/
short mh_type; /*记录存储的类型,是ARP还是TCP等*/
short mh_flags; /*标示是否是一个数据的头部*/
char* mh_data; /*指示数据开始的位置*/
}M_head;
typedef struct pcb{
int a;
}Socket;
typedef struct mbuf{
M_head m_hdr;
Socket* m_socket; /*mbuf所属的pcb*/
char M_databuf[MAXSIZE];
}Mbuf;
#define m_next m_hdr.mh_next
#define m_len m_hdr.mh_len
#define m_type m_hdr.mh_type
#define m_flags m_hdr.mh_flags
#define m_nexrpkt m_hdr.mh_nextpkt
#define m_data m_hdr.mh_data
#define m_nextpkt m_hdr.mh_nextpkt
struct mbuf MbufTbl[BUFSIZE];
Mbuf* MbufList;
Mbuf* MbufFreeList;
void Mbuf_InitList();
Mbuf* Mbuf_Create(char* p_buff,int type,int len);
void Mbuf_Transf(Mbuf* pm_buf,int type,int len);
int Mbuf_GetLen(Mbuf* pm_buf);
void Mbuf_Add(Mbuf* pm_buf,Mbuf* pm_buf2);
void Mbuf_Free(Mbuf* pm_buf);
//void m_Remove(Mbuf* m,int type,int len);
void CopyChar(char* ch1,char* ch2,int len);
Mbuf* Mbuf_Get();
void Mbuf_GetData(Mbuf** pm_buf,char* p_char,int len);
#endif
********************************************************************************************************
#include "m.h"
#include "string.h"
/*
*********************************************************************************************************
* strToBuf
*
* Description: 将结构体转换成字节流
*
* Arguments : char* p_struct 指向结构体的字节指针
* char* p_byte 转换后得到的字节流存储在该处
* int s_size 结构体占内存空间大小
*
* Returns : void
*
* Notes : 例,结构体类型Test1 test,strToBuf((char*)&test,p_byte,sizeof(test));即可
*
*********************************************************************************************************
*/
void strToBuf(char *p_struct,char* p_byte,int s_size){
int i =0;
for(;i<s_size;i++){ /*将结构体中的数据一个字节一个字节的复制到字符数组中*/
*p_byte=(char)*p_struct;
p_byte++;
p_struct++;
}
}
/*
*********************************************************************************************************
* Mbuf_InitList
*
* Description: 将请求分配的mbuf链成单向链表
*
* Arguments : void
*
* Returns : void
*
* Notes : 在主函数里面调用
*
*********************************************************************************************************
*/
void Mbuf_InitList(){
Mbuf* p_mbuf1;
Mbuf* p_mbuf2;
int i;
p_mbuf1 = &MbufTbl[0];
p_mbuf2 = &MbufTbl[1];
for (i = 0; i < BUFSIZE-1; i++) { /*将MbufTbl链成链表,生成MbufFreeList*/
p_mbuf1->m_next=p_mbuf2;
strcpy(p_mbuf1->M_databuf," ");
p_mbuf1++;
p_mbuf2++;
}
p_mbuf1->m_hdr.mh_next=(Mbuf*)0; /*p_mbuf1指向MbufTbl[BUFSIZE-1],它的m_next指向一个空buf*/
strcpy(p_mbuf1->M_databuf," ");
MbufFreeList = &MbufTbl[0]; /*MbufFreeList指向MbufTbl[0],即链表的起始位置*/
}
/*
*********************************************************************************************************
* Mbuf_Get
*
* Description: 向MbufFreeList申请一个Mbuf
*
* Arguments : void
*
* Returns : Mbuf* 申请到的Mbuf指针
*
* Notes : 当MbufFreeList为空时,申请到一个空指针
*
*********************************************************************************************************
*/
Mbuf* Mbuf_Get(){
if(MbufFreeList==(Mbuf*)0) /*当MbufFreeList为空时,返回一个空指针*/
{
return (Mbuf*)0 ;
}else
{
Mbuf* p_mbuf = MbufFreeList; /*MbufFreeList不为空,则从链表上取下一个*/
MbufFreeList = MbufFreeList->m_next;
p_mbuf->m_next = (Mbuf*)0;
return p_mbuf;
}
}
/*
*********************************************************************************************************
* Mbuf_Create
*
* Description: 将指定长度的数据存入一个Mbuf数据链表中
*
* Arguments : char* p_buff 该指针指向需要存储的数据的起始位置
* int type 记录存储的数据原属于的结构体类型(ARP、TCP等)
* int len 需要存的数据长度
*
* Returns : Mbuf* 指向数据链表表头
*
* Notes : 当存储空间不够的时候,存储失败(还未处理)
*
*********************************************************************************************************
*/
Mbuf* Mbuf_Create(char* p_buff,int type,int len){
struct mbuf* m_head;
struct mbuf* m_end;
int head = 1;
int templen = len;
do{
struct mbuf* temp = Mbuf_Get(); /*申请一个Mbuf*/
if(templen > MAXSIZE) /*如果需要存储的数据长度大于MAXSIZE*/
{
temp->m_len = MAXSIZE; /*mbuf中的m_len成员值为MAXSIze,否则等于len*/
}
else
{
temp->m_len = templen;
}
if(head==1){ /*如果是链表的头部,则将m_flags设为1,标示其为头部*/
temp->m_flags = 1;
head = 0;
m_head = temp;
m_end = temp;
}
else{
temp->m_flags = 0; /*如果不是头部,则将申请到的Mbuf加到链表尾部*/
m_end->m_next = temp;
m_end = temp;
}
temp->m_type = type;
temp->m_data = temp->M_databuf; /*将m_data指针指向数据起始位置*/
CopyChar(temp->M_databuf,p_buff+(len-templen),temp->m_len);
/*将数据复制到Mbuf中的M_databuf中*/
templen = templen-MAXSIZE; /*如果templen大于MAXSIZE,标示还有数据要存*/
/*如果小于或者等于,表示数据已经存完*/
}while(templen>0);
return m_head;
}
/*
*********************************************************************************************************
* CopyChar
*
* Description: 从一个ch2复制指定长度的数据到ch1
*
* Arguments : char* ch1 该指针指向需要复制数据的数组
* char* ch2 该指针指向将被复制数据的数组
*
* Returns : void
*
* Notes : 当ch2存的有用数据长度小于len时,可能会复制到一些无用的数据
*
*********************************************************************************************************
*/
void CopyChar(char* ch1,char* ch2,int len){
int i;
for(i=0;i<len;i++){ /*复制len个字节*/
if(ch2!="\0")
*ch1=*ch2;
ch2++;
ch1++;
}
return;
}
/*
*********************************************************************************************************
* Mbuf_Free
*
* Description: 释放一个Mbuf
*
* Arguments : Mbuf* pm_buf 该指针指向需要释放的Mbuf
*
* Returns : void
*
*
*********************************************************************************************************
*/
void Mbuf_Free(Mbuf* pm_buf){
pm_buf->m_len = 0; /*将里面的数据都清空后添加到MbufFreeList的头部*/
pm_buf->m_nextpkt = (Mbuf*)0;
pm_buf->m_data = " ";
pm_buf->m_flags = 0;
pm_buf->m_type = 0;
strcpy(pm_buf->M_databuf," ");
pm_buf->m_socket = (Socket*)0;
pm_buf->m_next = MbufFreeList;
MbufFreeList = pm_buf;
}
/*
*********************************************************************************************************
* Mbuf_Getlen
*
* Description: 得到数据链表中存储的数据总长度
*
* Arguments : Mbuf* pm_buf 该指针指向需要计算数据长度的Mbuf数据链表首部
*
* Returns : int 返回数据总长度
*
*
*********************************************************************************************************
*/
int Mbuf_Getlen(Mbuf* pm_buf){
Mbuf* temp_buf = pm_buf;
int templen=0;
do{ /*若temp_buf不为空,则总长度加上temp_buf->m_len*/
templen+=temp_buf->m_len;
temp_buf = temp_buf->m_next;
}while(temp_buf!=(Mbuf*)0);
return templen;
}
/*
*********************************************************************************************************
* Mbuf_GetData
*
* Description: 从数据链表pm_buf中取出指定数据放入ch中
*
* Arguments : Mbuf** pm_buf 指向存储了数据的数据链表地址的指针,取出数据后,链表指针也会发生变化
* 所以用了2级指针
* char* ch 取出的数据放入ch中
* int len 需要取的数据长度
*
* Returns : void
*
*
* Note : 第一个参数为二级指针
*
*********************************************************************************************************
*/
void Mbuf_GetData(Mbuf** pm_buf,char* ch,int len){
int templen=len;
char* temp1 = ch;
Mbuf* temp_buf;
do{
char* temp2 = (*pm_buf)->m_data;
if((*pm_buf)==(Mbuf*)0){
printf("Data Not Enough!\n");
}
if(templen>(*pm_buf)->m_len) templen = (*pm_buf)->m_len;
CopyChar(temp1,temp2,templen);
temp1 = temp1+templen;
temp_buf = *pm_buf; /*temp_buf指向当前的Mbuf,当pm_buf指向下一个时,则释放temp_buf*/
if(templen == temp_buf->m_len){ /*当一个Mbuf中的数据全部取出时需要释放掉*/
*pm_buf = (*pm_buf)->m_next;
Mbuf_Free(temp_buf);
}
else{
temp_buf->m_data = (*pm_buf)->M_databuf+templen;
/*如果数据未全部取出,则修改m_data(数据起始位置)的值*/
temp_buf->m_len = (*pm_buf)->m_len-templen;
}
len = len-templen; /*每取出templen个数据之后,len的值都要减去templen*/
templen = len;
}while(len>0);
return ;
}
/*
*********************************************************************************************************
* Mbuf_Add
*
* Description: 将数据链表pm_buf2链接到pm_buf1的尾部
*
* Arguments : Mbuf* pm_buf1 数据链表1,添加之后在前面
* Mbuf* pm_buf2 数据链表2,添加之后在后面
*
* Returns : void
*
*
*********************************************************************************************************
*/
void Mbuf_Add(Mbuf* pm_buf1,Mbuf* pm_buf2){
Mbuf* temp_buf = pm_buf1;
while(temp_buf->m_next!=(Mbuf*)0) /*先找到pm_buf1链表的尾部,将尾部Mbuf的m_next指向pm_buf2即可*/
temp_buf = temp_buf->m_next;
temp_buf->m_next = pm_buf2;
}