Отправка указателя на символ с UDP в C - PullRequest
1 голос
/ 05 августа 2010

У меня есть структура, которую я отправляю в сокет 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);

Есть ли более чистый способ сделать это или это единственный способ?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 05 августа 2010

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

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

0 голосов
/ 05 августа 2010

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

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 голосов
/ 05 августа 2010

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

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

SO-1

SO-2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...