在C中通过UDP在结构中发送动态数组

在C中通过UDP在结构中发送动态数组,c,arrays,dynamic,udp,C,Arrays,Dynamic,Udp,我正在编写一个代码,其中一个结构的成员是动态数组(在运行时之前大小未知)。 我需要通过UDP连接发送此结构,并能够读取和处理另一端的数据 我知道我可以使用指针和malloc来定义动态数组,但我不能通过UDP发送指针。我也在努力避免序列化 结构类似于这样,用户必须输入ID来定义消息类型以及数组中的消息 struct foo { unsigned int ID; unsigned int Num; unsigned int size; char arr[size];

我正在编写一个代码,其中一个结构的成员是动态数组(在运行时之前大小未知)。 我需要通过UDP连接发送此结构,并能够读取和处理另一端的数据

我知道我可以使用指针和malloc来定义动态数组,但我不能通过UDP发送指针。我也在努力避免序列化

结构类似于这样,用户必须输入ID来定义消息类型以及数组中的消息

struct foo
{
    unsigned int ID;
    unsigned int Num;
    unsigned int size;
    char arr[size]; //I know this is not acceptable in C, just typing to show my question.
};

是否有其他方法来创建可以通过UDP套接字发送的动态数组?在接收方处理此问题的最佳方法是什么?

您可以定义一个具有最小数组的结构,并为具有较大数组的结构分配内存

下面的代码示例不是有效的C,它不完整。当通过网络发送到不同的机器时,它也不能处理
int
值的字节顺序或大小差异

struct foo
{
    unsigned int ID;
    unsigned int Num;
    unsigned int size;
    char arr[1];
};

int size = 123;

int i;
int ret;

struct foo *ptr = malloc(offsetof(struct foo, arr) + size);

ptr->ID = 42;
ptr->Num = 99;
ptr->size = size;
for(i=0; i<ptr->size; i++)
{
     ptr->arr[i] = data;
}


ret = sendto(sockfd, ptr, offsetof(struct foo, arr) + size, flags,
           dest_addr, addrlen);
structfoo
{
无符号整数ID;
无符号整数;
无符号整数大小;
char-arr[1];
};
int size=123;
int i;
int ret;
结构foo*ptr=malloc(偏移量(结构foo,arr)+大小);
ptr->ID=42;
ptr->Num=99;
ptr->尺寸=尺寸;
对于(i=0;isize;i++)
{
ptr->arr[i]=数据;
}
ret=发送到(sockfd、ptr、offsetof(struct foo、arr)+大小、标志、,
目的地地址,地址);
编译器不关心您访问的数组索引是否大于您在结构声明中定义的索引。您必须检查代码中的索引以避免内存访问错误

接收器可以将
recvfrom()
MSG_PEEK
和标头的大小(
offsetof(struct foo,arr)
)一起使用到临时结构
struct foo tmp中
首先,接下来根据
大小
字段分配内存,然后将结构的完整大小读取到动态分配的内存中。另见

或者为
recvfrom()
使用最大大小的固定缓冲区,然后将数据复制到动态分配的结构中。
recvfrom()
的返回值将告诉您所需的大小

根据Matthias Simon答案中的建议进行编辑:

如果编译器支持零大小的数组,那么代码可以简化一点


在结构定义中,可以使用
char-arr[0]而不是
字符arr[1]。这允许在
malloc()
sendto()
recvfrom()
中使用
sizeof struct foo
而不是
offsetof(struct foo,arr)
来定义具有最小数组的结构,并为具有较大数组的结构分配内存

下面的代码示例不是有效的C,它不完整。当通过网络发送到不同的机器时,它也不能处理
int
值的字节顺序或大小差异

struct foo
{
    unsigned int ID;
    unsigned int Num;
    unsigned int size;
    char arr[1];
};

int size = 123;

int i;
int ret;

struct foo *ptr = malloc(offsetof(struct foo, arr) + size);

ptr->ID = 42;
ptr->Num = 99;
ptr->size = size;
for(i=0; i<ptr->size; i++)
{
     ptr->arr[i] = data;
}


ret = sendto(sockfd, ptr, offsetof(struct foo, arr) + size, flags,
           dest_addr, addrlen);
structfoo
{
无符号整数ID;
无符号整数;
无符号整数大小;
char-arr[1];
};
int size=123;
int i;
int ret;
结构foo*ptr=malloc(偏移量(结构foo,arr)+大小);
ptr->ID=42;
ptr->Num=99;
ptr->尺寸=尺寸;
对于(i=0;isize;i++)
{
ptr->arr[i]=数据;
}
ret=发送到(sockfd、ptr、offsetof(struct foo、arr)+大小、标志、,
目的地地址,地址);
编译器不关心您访问的数组索引是否大于您在结构声明中定义的索引。您必须检查代码中的索引以避免内存访问错误

接收器可以将
recvfrom()
MSG_PEEK
和标头的大小(
offsetof(struct foo,arr)
)一起使用到临时结构
struct foo tmp中
首先,接下来根据
大小
字段分配内存,然后将结构的完整大小读取到动态分配的内存中。另见

或者为
recvfrom()
使用最大大小的固定缓冲区,然后将数据复制到动态分配的结构中。
recvfrom()
的返回值将告诉您所需的大小

根据Matthias Simon答案中的建议进行编辑:

如果编译器支持零大小的数组,那么代码可以简化一点


在结构定义中,可以使用
char-arr[0]而不是
字符arr[1]。这允许在
malloc()
sendto()
recvfrom()
中使用
sizeof struct foo
而不是
offsetof(struct foo,arr)
MSG_PEEK

通过UDP发送动态大小的结构没有什么特别之处。一般来说,你只需要分配足够的内存,就像博多在回答中描述的那样。 另外,请看一下GCC手册:我希望这会有所帮助。不要忘记UDP消息有大小限制

[…]我也在努力避免序列化

我经常看到人们避免使用编解码器,因为他们的目标是提高性能。最后,由于端交换和打包问题,他们得到了相反的结果。
序列化是您的朋友,尤其是在与其他进程通信时。值得一读的是

通过UDP发送动态大小的结构没有什么特别之处。一般来说,你只需要分配足够的内存,就像博多在回答中描述的那样。 另外,请看一下GCC手册:我希望这会有所帮助。不要忘记UDP消息有大小限制

[…]我也在努力避免序列化

我经常看到人们避免使用编解码器,因为他们的目标是提高性能。最后,由于端交换和打包问题,他们得到了相反的结果。
序列化是您的朋友,尤其是在与其他进程通信时。值得一读的是

对不起,这真的很广泛。事实上,它似乎包含在