数据报的可变部分的设计

IP数据报,其可变部分可变是如何实现的?在这里插入图片描述
假设我们在网络通信过程中使用的数据缓冲区,缓冲区包括一个num, size和data字段,分别标识数据的块号,长度和传输的数据,我们设计思路如下:

  1. 定长数据缓冲区,设置一个足够大小MAXSIZE的数据缓冲区。
  2. 设置一个指向实际数据的指针,每次使用时,按照数据的长度动态的开辟数据缓冲区的空间。我们从实际场景中应用来考虑他们的优劣,主要考虑点有:缓冲区空间的开辟,释放和访问.

1 定长包:

#define MAX_SIZE 4096 //4K
typedef struct data_buffer
{
	int num;
	int size;
	char data[MAX_SIZE];//该结构体变量大小应该等于4K,使得能将结构体变量数据一次导入内存,不需要调动2次(两个页),且需要储存在硬盘时也不需要两个页来存储
}data_buffer;


//sizeof(int)+sizeof(size)+sizeof(char)*MAXSIZE;

使用定长数组作为数据缓冲区,为了避免造成缓冲区溢出,数组设计是大开小用,而实际使用过程中,达到MAXSIZE长度的数据很少,那么多数情况下,缓冲区的大部分空间都浪费了,也会造成不必要的流量浪费。
但是使用过程很简单,数据空间的开辟和释放简单,无需程序员考虑额外的操作。

2 指针数据包

如果你将上面的长度为MAXSIZE的定长数组换为指针,每次使用时动态的开辟CURSIZE 大小的空间,那么免造成 MAXSIZE - CURSIZE空间的浪费,只浪费了一个指针域的空间。而申请的堆空间相对于栈空间来说大得多得多。

//#define MAX_SIZE 4096 //4K
typedef struct data_buffer
{
	int num;
	int size;
	char * data;
}data_buffer;
//sizeof(int)+sizeof(size)+sizeof(char *);
//但需要申请堆空间和释放

int main()
{
	data_buffer * pbuff = (data_buffer *)malloc(sizeof(data_buffer));
	if (pbuff == NULL)
	{
		exit(EXIT_FAILURE)
	}
	pbuff->size = CURSIZE;//假设CURSIZE为发送数据长度
	pbuff->data = (char *)malloc(sizeof(char )*CURSIZE);
	if (pbuff->data == NULL)
	{
		exit(EXIT_FAILURE)
	}
	free(pbuff->data);
	free(pbuff);

	pbuff = NULL;
}

使用指针结果作为缓冲区,只多使用了一个指针大小的空间,无需使用MAXSIZE 长度的数组,不会造成空间的大量浪费。但那是开辟空间时,需要额外开辟数据域的空间,施放时候也需要显示释放数据域的空间,但是实际使用过程中,往往在函数中开辟空间,然后返回给使用者指向 struct point_buffer 的指针,这时候我们并不能假定使用者了解我们开辟的细节,并按照约定的操作释放空间,因此使用起来多有不便,甚至造成内存泄漏。

3 变长数据缓冲区

定长数组使用方便,但是却浪费空间。指针形式只多使用了一个指针的空间,不会造成大量空间分浪费,但是使用起来需要多次分配,多次释放,那么有没有一种实现方式既不浪费空间,又使用方便的呢?

#define MAX_SIZE 4096 //4K
typedef struct data_buffer
{
	int num;
	int size;
	char  data[];
}data_buffer;
//sizeof(int)+sizeof(size)
//使用时,只需要开辟一次空间即可

int main()
{
	int n = strlen("sqhlll") + 1;
	data_buffer * pbuff = (data_buffer *)malloc(sizeof(data_buffer)+n);
	if (pbuff == NULL)
	{
		exit(EXIT_FAILURE);
	}
	pbuff->num = 1;
	pbuff->size = n;
	memcpy(pbuff->data, "sqhlll", n);

	free(pbuff);
	pbuff = NULL;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值