1

我想在 C 中定义一个结构用于网络传输,例如我想传输一个 Animal 结构,其中包含可变长度的动物名称。

AFAIK,一种方法是using a predefined length of char array,或者using a buffer在结构中,我们可以解析缓冲区(例如,前4个字节是动物名称长度,后面是动物名称,以及其他字段的长度和其他字段的值),优势后一种方法的最大特点是它允许变量名长度,如以下代码所示:

struct Animal
{
    char   name[128];
    int    age;
}

或者:

struct Animal
{
    int    bufferLen;
    char*  pBuffer;
}

我的问题是:我的方法正确吗?即,有标准的传输结构的方法,还有更好的方法吗?

我的第二个问题是:我是否需要注意填充,即使用#pragma pack(push/pop, n)

提前致谢!

4

1 回答 1

3

两者都可以正常工作,但是,如果您使用固定长度的打包 sturct,则处理起来会稍微容易一些,但是您可能会发送比您需要的更多的数据,例如,以下代码,假设一个4 字节整数,将发送132字节:

//packed struct
struct Animal {
    char   name[128];
    int    age;
};

Animal a = {"name", 2};
send(fd, &a, sizeof(a), 0);
//and you're done

另一方面,可变长度字段将需要更多的工作来分配内存并打包在单个数据包中,但您将能够发送所需的确切字节数,9在这种情况下为字节:

//not necessarily packed   
struct Animal {
    char   *name;
    int    age;
};

//some arbitrary length
int name_length = 50;
//you should check the result of malloc
Animal a = {malloc(name_length), 2}; 

//copy the name
strcpy(a.name, "name");

//need to pack the fields in one buff    
char *buf = malloc(strlen(a.name)+ 1 + sizeof(a.age));
memcpy(buf, a.name, strlen(a.name)+1);
memcpy(buf, &a.age, sizeof(a.age));

send(fd, buf, strlen(a.name)+ 1 + sizeof(a.age));
//now you have to do some cleanup
free(buf);
free(a.name);

编辑:当然,如果您想自己实现它,您可以使用库为您序列化数据。此外,请查看Beej 网络编程指南中的示例序列化代码

于 2012-11-07T05:52:10.493 回答