在C中使用UDP发送字符指针

发布于 2024-09-12 21:01:17 字数 761 浏览 4 评论 0原文

我有一个要发送到 UDP 套接字的结构:

typedef struct
{
    char field_id;
    short field_length;
    char* field;
} field_t, *field_p;

一旦在 UDP 服务器端接收到,我就能够读取 field_idfield_length,但是指向 < code>field 正如预期的那样无效。

正确发送和接收动态 char* 的最佳方法是什么?

我有一个在客户端使用 memcpy 的基本解决方案:

char* data = 
    (char*)malloc(sizeof(field_t) + (sizeof(char) *  strlen(my_field->field)));
memcpy(data, my_field, sizeof(field_t));
memcpy(data+sizeof(field_t), my_field->field, strlen(my_field->field) + 1);

在服务器端:

field_p data = (field_p)buffer;
field_string = (char*)buffer+sizeof(field_t);

是否有更干净的方法来执行此操作,或者这是唯一的方法?

谢谢。

I have a struct that I am sending to a UDP socket:

typedef struct
{
    char field_id;
    short field_length;
    char* field;
} field_t, *field_p;

I am able to read the field_id and field_length once received on the UDP server-side, however the pointer to field is invalid as expected.

What is the best method to properly send and receive a dynamic char*?

I have a basic solution using memcpy on the client side:

char* data = 
    (char*)malloc(sizeof(field_t) + (sizeof(char) *  strlen(my_field->field)));
memcpy(data, my_field, sizeof(field_t));
memcpy(data+sizeof(field_t), my_field->field, strlen(my_field->field) + 1);

And on the server side:

field_p data = (field_p)buffer;
field_string = (char*)buffer+sizeof(field_t);

Is there a cleaner way of doing this or is this the only way?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

GRAY°灰色天空 2024-09-19 21:01:17

当然,您不能通过套接字发送指针 - 删除 char* 字段; 成员。相反,只需将 id 和 size 对与数据本身一起附加即可。使用 writev(2)sendmsg(2) 以避免在缓冲区之间移动数据。

注意结构成员对齐和填充和数字字节序

You of course cannot send a pointer over a socket - get rid of the char* field; member. Instead, just append id and size pair with the data itself. Use writev(2) or sendmsg(2) to avoid moving data around from buffer to buffer.

Watch out for structure member alignment and padding and number endianness.

眼藏柔 2024-09-19 21:01:17

序列化是你的朋友。

相关链接:

SO-1

SO-2

Serialization is your friend.

Related Links:

SO-1

SO-2

小糖芽 2024-09-19 21:01:17

将您的结构定义为:

typedef struct
{
    uint8_t  field_id;
    uint16_t field_length;
    char     field[0]; // note: in C99 you could use char field[];
} field_t, *field_p;

然后,文本缓冲区将立即跟随您的结构。只需记住一些技巧即可:

// initialize structure
field_t *
field_init (uint8_t id, uint16_t len, const char *txt)
{
    field_t *f = malloc (sizeof (field_t + len)); // note "+ len";
    f->field_id  = id;
    f->field_length = len;
    memcpy (f->field, txt, len);
    return f;
}

// send structure
int
field_send (field_t *f, int fd)
{
    return write (fd, f, sizeof (*f) + f->field_length); // note "+ f->field_length"
}

不过,我认为这不是标准的。然而,大多数编译器(GCC && MSVC)应该支持这一点。如果您的编译器不支持零大小的数组,您可以使用单元素字符数组 - 只需记住在计算数据包大小时减去额外的一个字节即可。

Define your structure as:

typedef struct
{
    uint8_t  field_id;
    uint16_t field_length;
    char     field[0]; // note: in C99 you could use char field[];
} field_t, *field_p;

Then, text buffer will immediately follow your structure. Just remember a few tricks:

// initialize structure
field_t *
field_init (uint8_t id, uint16_t len, const char *txt)
{
    field_t *f = malloc (sizeof (field_t + len)); // note "+ len";
    f->field_id  = id;
    f->field_length = len;
    memcpy (f->field, txt, len);
    return f;
}

// send structure
int
field_send (field_t *f, int fd)
{
    return write (fd, f, sizeof (*f) + f->field_length); // note "+ f->field_length"
}

I don't think it's standard, though. However, most compilers (GCC && MSVC) should support this. If your compiler does not support zero-sized array, you can use one-element char array - just remember to subtract extra one byte when calculating packet size.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文