1

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.

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

A slight bit of pedantry: you can send a pointer over a socket, but unless the other end of the socket is the same program, or something sharing the same memory space, it won't do you any good.
Yo can send yo mama over a socket :)
0

Serialization is your friend.

Related Links:

SO-1

SO-2

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.