Отправка символьного указателя с UDP в C

У меня есть структура, которую я отправляю на сокет UDP:

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

Я могу читать field_id и field_length после того, как полученный на серверной стороне UDP, однако указатель на field недопустимо как ожидалось.

Что лучший метод должен правильно отправить и получить динамический символ*?

У меня есть основное использование решения 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);

Существует ли более чистый способ сделать это, или действительно ли это - единственный путь?

Спасибо.

1
задан Trevor 5 August 2010 в 16:27
поделиться

3 ответа

Вы, конечно, не можете отправить указатель через сокет - избавьтесь от поля char *; . Вместо этого просто добавьте пару идентификаторов и размеров к самим данным. Используйте writev (2) или sendmsg (2) , чтобы избежать перемещения данных из буфера в буфер.

Следите за выравниванием и заполнением элементов структуры и порядком следования байтов .

2
ответ дан 2 September 2019 в 22:24
поделиться

Сериализация - ваш друг.

Ссылки по теме:

SO-1

SO-2

0
ответ дан 2 September 2019 в 22:24
поделиться

Определите вашу структуру как:

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) должны это поддерживать. Если ваш компилятор не поддерживает массив нулевого размера, вы можете использовать одноэлементный массив char - просто не забудьте вычесть лишний один байт при вычислении размера пакета.

0
ответ дан 2 September 2019 в 22:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: