Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用C语言定义网络通信的结构_C++_C_Memory_Struct - Fatal编程技术网

C++ 用C语言定义网络通信的结构

C++ 用C语言定义网络通信的结构,c++,c,memory,struct,C++,C,Memory,Struct,我想在C中定义一个用于网络传输的结构,例如,我想传输一个动物结构,它包含一个可变长度的动物名称 好的,一种方法是使用预定义长度的字符数组,或者在结构中使用缓冲区,我们可以解析缓冲区(例如,前4个字节是动物名称长度,后面是动物名称,以及其他字段的长度和其他字段的值),后一种方法的优点是它允许可变名称长度,如下代码所示: struct Animal { char name[128]; int age; } 或: 我的问题是:我的方法正确吗?i、 例如,有标准的方法来传输s

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

好的,一种方法是
使用预定义长度的字符数组
,或者
在结构中使用缓冲区
,我们可以解析缓冲区(例如,前4个字节是动物名称长度,后面是动物名称,以及其他字段的长度和其他字段的值),后一种方法的优点是它允许可变名称长度,如下代码所示:

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

我的问题是:我的方法正确吗?i、 例如,有标准的方法来传输struct,还有更好的方法吗

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


提前谢谢

两者都可以正常工作,但是,如果您使用固定长度的压缩
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);

编辑:如果您想自己实现,当然可以使用库来序列化数据。此外,请检查

中的示例序列化代码。您可以使用两种方法使其工作,两者都没有错。关于pack pragma,同样,您可以使用与pack一起使用或不使用pack来编写代码。尝试直接发送原始数据结构通常不是一个好主意。您应该使用序列化格式,如JSON、XML、XDR等。是的,填充很重要。例如,在虚拟机器上的第一个结构中会有填充,其中
sizeof(int)==alignof(int)==5
。但是,如果您希望代码是可移植的,那么需要记住的不仅仅是填充。例如,当发送方和接收方具有不同的端点时会发生什么?或者不同的
sizeof(int)
?Barmar的评论是正确的:发送原始结构通常不是一个好主意。发送原始指针永远不会起作用。发送整数时还必须小心,因为发送方和接收方的字节顺序可能不同(例如ARM(用于手机)和x86)。
//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);