1 数据包结构定义
1.1 数据包的结构
通信过程中数据包的传递如下:
我们改如何定义数据包结构呢?
- 数据包长度不固定,可长可短。
- 需支持头部的添加和移除。
- 简单易于使用。
数据包结构如下:
1.2 代码实现
首先看下整个工程文件的组成:
xnet_tiny.h中添加如下内容:
#ifndef XNET_TINY_H
#define XNET_TINY_H
#include <stdint.h>
#define XNET_CFG_PACKET_MAX_SIZE 1516 // 收发数据包的最大大小
/**
* 网络数据结构
*/
typedef struct _xnet_packet_t{
uint16_t size; // 包中有效数据大小
uint8_t * data; // 包的数据起始地址
uint8_t payload[XNET_CFG_PACKET_MAX_SIZE]; // 最大负载数据量
}xnet_packet_t;
xnet_packet_t * xnet_alloc_for_send(uint16_t data_size);
xnet_packet_t * xnet_alloc_for_read(uint16_t data_size);
void xnet_init (void);
void xnet_poll(void);
#endif // XNET_TINY_H
xnet_tiny.c中添加如下内容:
#include "xnet_tiny.h"
#define min(a, b) ((a) > (b) ? (b) : (a))
static xnet_packet_t tx_packet, rx_packet; // 接收与发送缓冲区
/**
* 分配一个网络数据包用于发送数据
* @param data_size 数据空间大小
* @return 分配得到的包结构
*/
xnet_packet_t * xnet_alloc_for_send(uint16_t data_size) {
// 从tx_packet的后端往前分配,因为前边要预留作为各种协议的头部数据存储空间
tx_packet.data = tx_packet.payload + XNET_CFG_PACKET_MAX_SIZE - data_size;
tx_packet.size = data_size;
return &tx_packet;
}
/**
* 分配一个网络数据包用于读取
* @param data_size 数据空间大小
* @return 分配得到的数据包
*/
xnet_packet_t * xnet_alloc_for_read(uint16_t data_size) {
// 从最开始进行分配,用于最底层的网络数据帧读取
rx_packet.data = rx_packet.payload;
rx_packet.size = data_size;
return &rx_packet;
}
/**
* 为发包添加一个头部
* @param packet 待处理的数据包
* @param header_size 增加的头部大小
*/
static void add_header(xnet_packet_t *packet, uint16_t header_size) {
packet->data -= header_size;
packet->size += header_size;
}
/**
* 为接收向上处理移去头部
* @param packet 待处理的数据包
* @param header_size 移去的头部大小
*/
static void remove_header(xnet_packet_t *packet, uint16_t header_size) {
packet->data += header_size;
packet->size -= header_size;
}
/**
* 将包的长度截断为size大小
* @param packet 待处理的数据包
* @param size 最终大小
*/
static void truncate_packet(xnet_packet_t *packet, uint16_t size) {
packet->size = min(packet->size, size);
}
/**
* 协议栈的初始化
*/
void xnet_init (void) {
}
/**
* 轮询处理数据包,并在协议栈中处理
*/
void xnet_poll(void) {
}
app.c:
#include <stdio.h>
#include "xnet_tiny.h"
int main (void) {
xnet_init();
printf("xnet running\n");
while (1) {
xnet_poll();
}
return 0;
}