«Объединить» структуру в массив символов - PullRequest
1 голос
/ 02 июня 2011

У меня есть структура, которая используется в моем интернет-приложении, которая выглядит следующим образом:

struct query {
     ushort trans_id;
     ushort flags;
     ushort opcode;
     ushort content_length;
     char content[512];
};

По сути, я просто пытаюсь взять эту структуру и превратить ее в «пакет» для отправки. Он должен иметь соответствующую длину и все. Так; если бы я мог, я бы хотел: запрос структуры q;

q.trans_id = 0x5544;
q.flags = 0x0000;
q.opcode = 0x0010;
q.content_length = 0x0001;
q.content[0] = '\0'; //I would want my packet to end up looking like this, when outputted to the socket:
//\x55\x44\x00\x00\x00\x10\x00\x01\x00
//and yes, it's going to be stored in a char buffer, but I'm not using any functions that will trim off any of the things past the null!

Я чувствую, что это относительно простой вопрос, на который, вероятно, можно ответить, приведя мои типы данных, но я думаю, что это немного сложнее.

Я также пытался использовать sprintf, но он превратил бы мои нули в фактические 0, поэтому 0x0000 станет 2 '0' ASCII-символами!

Ответы [ 2 ]

2 голосов
/ 02 июня 2011

Если вы хотите отправить его как пакет, вы должны быть осторожны с порядком байтов (htons).Создайте свою собственную функцию, которая создает «пакет».

  • Создайте достаточно большой буфер (статический массив должен хорошо работать)
  • Скопируйте (memcpy) каждый элемент вЭто.Не забывайте о htons

У вас может возникнуть соблазн просто write struct для сокета. Вы не должны делать это , так как нет гарантии, что расположение полей на принимающей машине будет одинаковым (заполнение?).

0 голосов
/ 02 июня 2011

Вы действительно можете просто привести указатель на вашу структуру к символу *, например:

#include <stdlib.h> /* for size_t */

....

struct query q;
/* fill in the struct ... */
char *packet = (char *)(&q);
size_t packet_size = sizeof(struct query);

Если вы хотите, чтобы размер пакета обрезал содержимое структуры запроса, вам придетсярассчитать разницу (используя, например, strnlen для содержимого и вычесть разницу)

РЕДАКТИРОВАТЬ: В качестве альтернативы для обрезки вы можете сделать:

int packet_size = (&(q.content[0]) + strnlen(q.content, 512)) - &q;
...