利用给出的数据结构:
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文件,确认其中内容是否与定义的结构一致。
源代码如下:
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdint.h>
5
6
7 typedef struct recv_data
8
9 {
10 uint32_t ip;
11
12 uint16_t port;
13
14 void*ptr;
15
16 uint16_t data_size;
17
18 char buff[4096];
19
20 } recv_data_t;
21
22
23 int main (int argc, char**argv)
24
25 {
26 FILE *fp;
27
28 recv_data_t data;
29
30 memset(&data, 0, sizeof(data));
31 uint32_t ip=3232261121u; //192.168.100.1的十进制表示
32 memcpy(&data.ip, &ip,sizeof(uint32_t));
33 data.port =9876;
34 data.data_size=strlen("text message, 1234567890!");
35
36 strcpy(data.buff, "test message, 1234567890!");
37
38 data.data_size = strlen(data.buff);
39
40 data.ptr = NULL;
41
42 fp = fopen ("wf.dat", "wb");
43 if (fp == NULL)
44 {
45 printf ("open file fail\n");
46
47 return-1;
48
49 }
50
51 fwrite (&data.ip,sizeof(data.ip),1,fp);
52 fwrite (&(data.port), sizeof(data.port), 1, fp);
53 fwrite (&(data.data_size), sizeof(data.data_size), 1, fp);
54 fwrite (data.buff, data.data_size, 1, fp);
55
56 fclose(fp);
57
58 fp = fopen("wf.dat","rb");
59
60 fread (&data.ip,sizeof(data.ip),1,fp);
61 printf("%u\n",data.ip);
62
63 fread (&(data.port),sizeof(data.port),1,fp);
64 printf("%d\n",data.port);
65
66 fread (&(data.data_size),sizeof(data.data_size),1,fp);
67 printf("%d\n",data.data_size);
68
69 fread (data.buff,data.data_size,1,fp);
70 printf("%s\n",data.buff);
71
72 fclose(fp);
73
74 return0;
75
76 }