UDP分包组包的类

分享一个自己写的udp分包组包的例子,一个包以32768为单位分包,每个包有序号,如果乱序或者是缺少,直接舍弃。(有点浪费资源)如果是要实现一个资源发送过程中乱序的重组,请自己修改吧,什么冒泡排序之类的。我就懒得写了。

声明:

typedef struct UDPData
{
	unsigned int index;	//包序号
	unsigned int part;	//块总数
	unsigned int npart;	//当前块序号
	unsigned int len;	//当前包数据字节数
	char data[32768];	//数据 32K
}UDPData;

class UDPSessions
{
public :
	UDPSessions(SOCKET h);
	UDPSessions();
	UDPSessions(SOCKET h , char * i , int p);
	int UDPSend(char * data , int len);
	int UDPRecv(char *& data);
	SOCKET hSocket;
	char ipaddr[32];
	int port;
private:
	int index;
};

定义:

#include "UDPSocket.h"

UDPSessions::UDPSessions(SOCKET h)
{
	hSocket = h;
	index = -1;
	port=0;
}

UDPSessions::UDPSessions(SOCKET h , char * i , int p)
{
	hSocket = h;
	index = 0;
	strcpy(ipaddr , i);
	port=p;
}
UDPSessions::UDPSessions()
{
	hSocket = NULL;
	index = -1;
}
int UDPSessions::UDPSend(char * data , int len)
{
	int retlen = 0;
	sockaddr_in    sin;
	sin.sin_family     = AF_INET;
	sin.sin_addr.S_un.S_addr  = INADDR_ANY;
	sin.sin_addr.S_un.S_addr  = inet_addr(ipaddr);
	sin.sin_port     = ntohs(port);
	int nLen = sizeof(sin);
	if(len < 32768)
	{
		UDPData udpdata;
		udpdata.index = index;
		udpdata.part = 1;
		udpdata.npart = 1;
		udpdata.len = len;
		memcpy(udpdata.data , data , len);
		retlen = sendto(hSocket , (char *)&udpdata , sizeof(udpdata) ,0, (sockaddr*)&sin, nLen);
	}
	else
	{
		int n;
		if(len % 32768)
			n = len/32768 + 1;
		else 
			n = len/32768;
		for(int i=0 ; i<n ;i++)
		{
			UDPData udpdata;
			udpdata.index = index;
			udpdata.part = n;
			udpdata.npart = i;
			if(i == n-1)
			{
				udpdata.len = len-i*32768;
				memcpy(&udpdata.data , data+i*32768 , len-i*32768);
			}
			else
			{
				udpdata.len = 32768;
				memcpy(&udpdata.data , data+i*32768 , 32768);		
			}
			retlen = sendto(hSocket , (char *)&udpdata , sizeof(udpdata) , 0,(sockaddr*)&sin, nLen);
		}
	}
	index ++;
	return retlen;
}

int UDPSessions::UDPRecv(char *& data)
{
	int retlen = 0;
	int fpart = 0;
	UDPData udpdata;
	sockaddr_in    addr;
	int      nLen = sizeof(addr);
	while(1)
	{
		int len = recvfrom(hSocket, (char *)&udpdata, sizeof(udpdata), 0, (sockaddr*)&addr, &nLen);
		retlen += udpdata.len;
		if(udpdata.part == 1)			//只有一个分块
		{
			index = udpdata.index;
			data = (char *)malloc(udpdata.len);
			memcpy(data , &udpdata.data , udpdata.len);
			break;
		}
		else if(udpdata.part > 1)
		{
			if(index == udpdata.index) //同一个包的块
			{
				if(fpart+1 == udpdata.npart)	//顺序包
				{
					memcpy(data+udpdata.npart*32768 , &udpdata.data , udpdata.len);
					fpart ++;
				}
				else
				{
					retlen = -1;
					break;
				}
				if(udpdata.npart == udpdata.part-1) //最后一个块
				{
					break;
				}
			}
			else						//新的包
			{
				if(udpdata.npart == 0)
				{
					data = (char *)malloc(udpdata.part*32768);
					memcpy(data , &udpdata.data , 32768);
					index = udpdata.index;
					fpart = 0;
				}
				else 
				{
					retlen = -1;
					break;
				}
			}
		}
		else
		{
			retlen = -1;
			break;
		}
	}
	return retlen ;
}


  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值