typedef struct node_s {
int type; /* 头部,可根据实际情况添加元素 */
int len; /* 头部,标识数据段已使用的长度 */
char value[0]; /* 数据段,柔性数组 */
} node_t;
所以,柔性数组实现扩展长度的结构体一句话概括就是:在结构体的最后加上一个长度为零的char数组。
用sizeof(node_t)可以发现,柔性数组是不占内存空间的。
如何添加一段数据到数据包呢?
1,初始化:
#define MAX_INFO_SIZE (x - sizeof(node_t))
node_t *nodeinfo;
char *mark;
node_info = (node_t *)malloc(sizeof(node_t) + MAX_INFO_SIZE);
if (node_info == NULL) {
mem_error();
}
memset(node_info, 0, sizeof(node_t) + MAX_INFO_SIZE);
node_info->type = your_type;
node_info->len = 0;
mark = &node_info->value;
即是:申请一段内存,初始化,将数据段的标志位mark指向value地址,还没有添加数据,所以len为0;
2,添加数据
for (data = x; data < y; data = next(x)) { /* 遍历那串数据,简化版 */
len = get_data_len(data);
if (node_info->len + len <= MAX_INFO_SIZE) {
memcpy(mark, data, len);
mark += len;
node_info->len += len;
} else {
send(node_info); /* 调用某协议发送出数据,简化版 */
memset(node_info, 0, sizeof(node_t) + MAX_INFO_SIZE);
node_info->type = your_type;
node_info->len = 0;
mark = &node_info->value;
memcpy(mark, data, len);
mark += len;
node_info->len += len;
}
}
send(node_info); /* 发送最后一个数据包 */
添加数据的操作即是:将数据拷贝到数据段,记录添加的长度,移动标记位以便下次添加。如果数据达到数据包最大值,发送掉这个包,然后继续添加操作。
这样,每个不大于x byte的数据包都填充好了data数据,并且利用通信机制发送到了另一个地方。
那“另一个地方”接收到了这个不大于x byte的数据包,如何从数据包里解析出data数据来呢?
3,解析数据
假设某台机器得到了这个数据包,要查看数据包里每个data的内容,如何解析?
node_t *node_info;
char *buf;
int len;
node_t *node_info;
get_info(node_info); /* 让node_info得到了那个不大于x byte的数据包,简化版 */
for (buf = node_info->value; buf < node_info->value + node_info->len; buf += len) {
data = (data_t *)buf; /* 从数据包里取到了一个data */
op(data); /* 查看数据包,简化版 */
len = get_data_len(data);
}
以上,利用柔性数组构造一个数据包,并进行封包,发包,解包的操作就完成了!
在实际生产应用中,要对数据包的头部扩展,其他的每一个操作都不会像例子的伪代码那样简单,但原理是一样的。
如果没有用过柔性数组的童鞋,可以思考一下:
为什么最后一个原始是0元素的数组而不是指针呢?假如不是C99怎么办?
---------------------------------这是分割线-------------------------------------
第一次写博客,实在不知道写什么东西,也发现即使是自己经常用,已经习以为常的小知识点,要用文字阐述清除,也是非常困难滴,文中肯定有很多不足,欢迎大家指正!