利用给出的数据结构:
typedef struct recv_data
{
char ip[32];
short port; //socket port
char buff[PACKET_SIZE];
short data_size;
void *ptr;
void *elm;
} PACKED recv_data_t;
PACKET_SIZE = 4096
1. 首先构造造一个binary文件;
2. 用lua脚本读取这个文件;
3. 解析这个文件。
本文只涉及第一项任务。
需要创建一个二进制文件(binary),并对构造的文件内容进行读写,将结构体成员信息数据都写入到二进制文件中并能识别它。
步骤:1. 利用fopen()函数来打开一个并创建一个二进制文件。
FILE *fp; /*FILE 是变量类型,是C中用于文件的标准数结构;声明fp是指向FILE类型的指针*/
fp = fopen ("wf.dat", "wb"); /*wb参数是只写打开或建立一个二进制文件,只允许写数据;fp是文件指针。*/
心路历程:起初,想利用fgets()函数来从参数stream所指的文件内读入字符并存到参数s所指的内存空间里,后来发现这样做不可行,会导致程序逻辑上错误,所以改用fwrite。
2. 为了程序的可扩展性,将数据结构修改如下:
typedef struct recv_data
{
uint32_t ip;
uint16_t port;
void *ptr;
uint16_t data_size;
char buff[4096];
} recv_data_t;
以前文件是定长的,现在修改为:buff 最大4096,具体长度由 data_size 确定,于是第一版的代码需要修改。
其中uint32_t表示:uint32_t unsigned int
uint16_t表示:uint32_t unsigned short
在程序中uint32_t、uint16_t都不是标准库的类型,而是扩展数据类型,编译时候会出现未声明错误,需要加上头文件#include <stdint.h>才行。
心路历程:(1)我的想法是用malloc函数给data_buff分配内存空间,数据大小由data_size确定,然后将值写入到文件中。那就要为其声明一个指针变量来实现,我定义了一个指针变量p不过这样做貌似画蛇添足。
(2)于是我将结构体的成员变量ip和buff修改为*ip和*buff,这样就分配了内存空间来将值存入到data.ip中。Buff要求大小是4096,就也用malloc函数分配那么大的内存来存放data_size的内容。
(3)后来发现结构体成员变量ip应该是unsigned int的值,而不是指针,于是又把代码修改了下。
3. 由fopen()函数创建并打开二进制文件后,处理过程如下:
(1)使用memset()函数将为结构体分配的内存空间初始化。
(2)由于ip是unsigned int类型的,所以先用sizeof计算ip的大小,再用memcpy()函数将32位ip 地址复制到结构体成员data.ip中。
(3)为端口号赋值。
(4)计算data的大小,data中的内容应该是字符串,所以用strcpy()函数将data_size的内容复制到data.buff中。
(5)由于*ptr和*elm是记录别的数据用的,可以认为是一个KEY,先把他初始化为NULL。
4. 处理完后,利用fwrite()函数将结构体中的数据依次写入到创建的binary文件中。
5. 利用fread()函数,按序将写入binary文件中的数据读出来。
6. 使用winhex工具,验证生成的binary文件,确认其中内容是否与定义的结构一致。
源代码如下: