m.c

#include "m.h"
#include "string.h"
#include "stdio.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(INT8U *p_struct,INT8U* p_byte,INT32U s_size){
	INT32U i =0;
	for(;i<s_size;i++){				/*将结构体中的数据一个字节一个字节的复制到字符数组中*/
		*p_byte=(INT8U)*p_struct;
		p_byte++;
		p_struct++;
	}
}


/*
*********************************************************************************************************
*                                            Mbuf_InitList
*
* Description: 将请求分配的mbuf链成单向链表
*
* Arguments  : void
*									
* Returns    : void	
*
* Notes		 : 在主函数里面调用			
*
*********************************************************************************************************
*/
void Mbuf_InitList(){
	Mbuf* p_mbuf1;				
	Mbuf* p_mbuf2;
	INT32U i;
	p_mbuf1 = &MbufTbl[0];
	p_mbuf2 = &MbufTbl[1];
	for (i = 0; i < BUFSIZE-1; i++) {				/*将MbufTbl链成链表,生成MbufFreeList*/
        p_mbuf1->m_next=p_mbuf2;
		p_mbuf1->m_nextpkt = (Mbuf*)0;
		p_mbuf1->m_socket = (void*)0;
		strcpy(p_mbuf1->M_databuf," ");
        p_mbuf1++;
        p_mbuf2++;
    }
	p_mbuf1->m_nextpkt = (Mbuf*)0;
	p_mbuf1->m_hdr.mh_next=(Mbuf*)0;			/*p_mbuf1指向MbufTbl[BUFSIZE-1],它的m_next指向一个空buf*/
	p_mbuf1->m_socket = (void*)0;
	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(INT8U* p_buff,INT32U type,INT32U len){
	struct mbuf* m_head;
	struct mbuf* m_end;
	INT32U seq = 0;
	INT32U head = 1;
	INT32S 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 = (INT32U)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);
		m_end->m_seq = seq;
		seq = seq+temp->m_len;
																      /*将数据复制到Mbuf中的M_databuf中*/
		if(templen>MAXSIZE)
		templen = templen-MAXSIZE;			      /*如果templen大于MAXSIZE,标示还有数据要存*/
		else templen = 0;
																      /*如果小于或者等于,表示数据已经存完*/
		
	}while(templen!=0);
	return m_head;
}



/*
*********************************************************************************************************
*                                            CopyChar
*
* Description: 从一个ch2复制指定长度的数据到ch1
*												
* Arguments  : char* ch1	该指针指向需要复制数据的数组
*			   char* ch2	该指针指向将被复制数据的数组	
*									
* Returns    : void
*
* Notes		 : 当ch2存的有用数据长度小于len时,可能会复制到一些无用的数据			
*
*********************************************************************************************************
*/
void CopyChar(INT8U* ch1,INT8U* ch2,INT32U len){
	INT32U 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){
	if(pm_buf->m_next!=(Mbuf*)0){
			pm_buf->m_next->m_nextpkt = pm_buf->m_nextpkt;
			pm_buf->m_next->m_socket = pm_buf->m_socket;
	}else{
			//如果里面的socket不为空,则将socket里的mbuf指针指向nextpkt
	}
	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 = (void*)0;
	pm_buf->m_next = MbufFreeList;
	MbufFreeList = pm_buf;	
}



/*
*********************************************************************************************************
*                                            Mbuf_Getlen
*
* Description: 得到数据链表中存储的数据总长度
*												
* Arguments  : Mbuf* pm_buf	该指针指向需要计算数据长度的Mbuf数据链表首部	
*									
* Returns    : int	 返回数据总长度
*			
*
*********************************************************************************************************
*/
INT32U Mbuf_GetLen(Mbuf* pm_buf){
	Mbuf* temp_buf = pm_buf;
	INT32U 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,INT8U* ch,INT32U len){
	
	INT32U   templen=len;
	INT8U* temp1 = ch; 	
	Mbuf* temp_buf;	   
	
	do{	
			
		INT8U* 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){
	INT32U templen; 
	Mbuf* temp_buf = pm_buf1;
	templen = Mbuf_GetLen(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;
	while(pm_buf2!=(Mbuf*)0){
		pm_buf2->m_seq+=templen;
		pm_buf2 = pm_buf2->m_next;
	}
}

/*
*********************************************************************************************************
*                                            Mbuf_Insert
*
* Description: 将一个数据包按照序号插入到数据包链表中
*												
* Arguments  : Mbuf* p_list	起始数据包链表
*					   Mbuf* p_pkt	接收到的需要进行插入的数据包	
*									
* Returns    : Mbuf*		插入后得到的数据包链表
*			
*
*********************************************************************************************************
*/
Mbuf* Mbuf_Insert(Mbuf* p_list,Mbuf* p_pkt){
	Mbuf* pm_buf = p_list;										/*用来保存表首位置*/
	if(p_list == (Mbuf*)0) return p_pkt;					/*如果p_list为空,则返回p_pkt*/
	if(p_list->m_seq > p_pkt->m_seq)						/*如果p_pkt的序号比P_list大,则放在表首*/
	{
		p_pkt->m_nextpkt = p_list;
		return p_pkt;
	}
	while(p_list->m_nextpkt!=(Mbuf*)0){					/*如果p_list的m_nextpkt指向的mbuf的序号大于p_pkt的序号,则将p_pkt插在p_list后面*/
		if(p_list->m_nextpkt->m_seq > p_pkt->m_seq){
			p_pkt->m_nextpkt = p_list->m_nextpkt;
			p_list->m_nextpkt = p_pkt;
			return pm_buf;
		}
		p_list = p_list->m_nextpkt;
	}
	p_list->m_nextpkt = p_pkt;								/*将p_pkt放在链表尾部*/
	return pm_buf;
}


/*
*********************************************************************************************************
*                                            Mbuf_FindSeq
*
* Description: 根据序号找到对应的数据包
*												
* Arguments  : Mbuf* p_list	数据包链表
*					   INT32U   seq			序号	
*									
* Returns    : Mbuf*		根据序号找到的数据包
*			
*
* Notes      : 可能返回的是空
*********************************************************************************************************
*/
Mbuf* Mbuf_FindSeq(Mbuf* p_list, INT32U seq){
	while(p_list!=(Mbuf*)0){
		if(seq==p_list->m_seq)
			return p_list;
		p_list = p_list->m_nextpkt;
	}
	return (Mbuf*)0;
}


/*
*********************************************************************************************************
*                                            Mbuf_FindAck
*
* Description: 根据确认号找到对应的数据包ack==p_list->m_seq+Mbuf_GetLen(p_list)
*												
* Arguments  : Mbuf* p_list	数据包链表
*					   INT32U   ack			确认号	
*									
* Returns    : Mbuf*		根据序号找到的数据包
*			
*
* Notes      : 可能返回的是空
*********************************************************************************************************
*/

Mbuf* Mbuf_FindAck(Mbuf* p_list, INT32U ack){
	while(p_list!=(Mbuf*)0){
		if(ack==p_list->m_seq+Mbuf_GetLen(p_list))
			return p_list;
		p_list = p_list->m_nextpkt;
	}
	return (Mbuf*)0;
}


/*
*********************************************************************************************************
*                                            Mbuf_GetpktSeq
*
* Description: 根据序号取下已收到的连续数据包
*												
* Arguments  : Mbuf** p_list			接收队列地址
*									
* Returns    : Mbuf*						已经接收到的连续数据
*			
*
* Notes      : 可能返回的是空
*********************************************************************************************************
*/
Mbuf* Mbuf_GetpktSeq(Mbuf** pp_list){
	Mbuf* p_temp;
	Mbuf* p_list = *pp_list;
	p_temp = (Mbuf*)0;

	while(p_list!=(Mbuf*)0){
		Mbuf_Add(p_temp,p_list);
																					/*如果p_list的m_nextpkt指向的mbuf与其连续,则取下来*/
		if(p_list->m_seq+Mbuf_GetLen(p_list)==p_list->m_nextpkt->m_seq)
			p_list = p_list->m_nextpkt;
		else
			break;
	}
	return p_temp;
}


/*
*********************************************************************************************************
*                                            Mbuf_GetpktACK
*
* Description: 根据确认号取下已被确认接收的连续数据包
*												
* Arguments  : Mbuf** p_list			发送缓存队列地址
*									
* Returns    : Mbuf*						已经被确认接收到的连续数据
*			
*
* Notes      : 可能返回的是空
*********************************************************************************************************
*/
Mbuf* Mbuf_GetpktAck(Mbuf** pp_list){
	Mbuf* p_temp;
	Mbuf* p_list = *pp_list;
	p_temp = (Mbuf*)0;

	while(p_list!=(Mbuf*)0){
		Mbuf_Add(p_temp,p_list);
		if(p_list->m_ack>=1)										/*如果p_list的接收次数m_ack大于等于1,则将其从发送缓存中删除*/
			p_list = p_list->m_nextpkt;
		else
			break;
	}
	return p_temp;

}


/*
*********************************************************************************************************
*                                            Mbuf_Freepkt
*
* Description:释放一个数据链表
*												
* Arguments  : Mbuf* p_list			链表首地址
*									
* Returns    : void				
*			
*
* Notes      : 注意m_nextpkt指向
*********************************************************************************************************
*/
void Mbuf_Freepkt(Mbuf* p_list){
	Mbuf* p_temp;
	while(p_list!=(Mbuf*)0){
		p_temp = p_list;
		p_list = p_list->m_next;
		Mbuf_Free(p_temp);
	}
	return;
}



/*
*********************************************************************************************************
*                                            Mbuf_GetDataFree
*
* Description:取出数据,但并不将数据从mbuf中删除掉
*												
* Arguments  : Mbuf* pm_buf		数据链表首地址
*						INT8U* ch			取出的数据存放的位置
*						INT32U len			需要取的数据长度
*									
* Returns    : void				
*			
*
* Notes      : void
*********************************************************************************************************
*/
void Mbuf_GetDataFree(Mbuf* pm_buf,INT8U* ch,INT32U len){
	
	INT32U   templen=len;
	INT8U* temp1 = ch; 	
	Mbuf* temp_buf;	   
	
	do{	
			
		INT8U* 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){				
			pm_buf = pm_buf->m_next;

		}
		len = len-templen;								/*每取出templen个数据之后,len的值都要减去templen*/
		templen = len;
			
	}while(len>0);
	return ;
}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值