Вопрос

Я пытаюсь отправить свою структуру через розетку UDP.

struct packet {int seqnum; Данные ChAR [BufferSize]; };

Так что у отправителя у меня есть

bytes = sizeof(packet);
char sending[bytes];
bzero(sending, bytes);
memcpy((void *) sending, (void *) &packet, sizeof(bytes));
bytes = sendto(sockfd, sending, sizeof(sending), 0,
    (struct sockaddr *) &client, clientSize);

Так что я надеюсь, что это копирует мою структуру в чар [].

На приемнике у меня есть

int bytes;
bytes = sizeof(struct Packet);
char recv[bytes];
bytes = recvfrom(sockfd, recv, bytes, 0,
    (struct sockaddr *) &client, &clientSize);
memcpy((void *) currentpkt, (void *) recv, bytes);

Однако на приемнике с memcpy ((void *) currentpkt, (void *) recv, байты); Я получаю ошибку:

Ошибка: невозможно преобразовать в тип указателя

Что я делаю не так? Есть ли лучший способ отправить мою структуру через розетку UDP?

***** ОБНОВИТЬ *****

Спасибо за ответы всем. В конце концов я пропустил «&», но теперь мой код выглядит так.

Отправитель:

void udt_send(struct Packet packet) {
    int bytes;
    bytes = sendto(sockfd, (char *) &packet, sizeof(packet), 0,
            (struct sockaddr *) &client, clientSize);
}

Получатель:

bytes = recvfrom(sockfd, (char *) &currentpkt, bytes, 0,
        (struct sockaddr *) &client, &clientSize);

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

Это было полезно?

Решение

currentpkt имеет структуру типа; Вам нужно получить указатель на структуру, чтобы заставить это работать:

memcpy(&currentpkt, recv, bytes);

Для вашего второго вопроса у вас есть другие проблемы. Что если вы получите больше байтов в пакете, чем sizeof(struct Packet)? Как это написано сейчас, вы переполняете свою структуру.

Что, если приложения клиента и сервера собираются с использованием разных компиляторов или настроек, или на платформах с разной эндозостью? В этом случае структура может быть разными размерами на двух платформах и может быть изложена в памяти по -разному.

Другие советы

Так что я думаю, что currentpkt это struct Packet, и что вы действительно хотели сказать &currentpkt.

Я мог бы также отметить, что memcpy() уже есть void * параметры, поэтому (void *) Деки не нужны.

memcpy((void *) currentpkt, (void *) recv, bytes);

Ваше сообщение об ошибке указывает на проблему листа. recv в порядке, так как это char[] (Нет проблем, преобразующих (void*)). Проблема заключается в том, что currentpkt Не должен быть типом указателя.

Это не объявлено в вашем фрагменте, поэтому я не знаю, что это такое, но я бы начал там.

Делать Memcpy от всей структуры-это действительно зло :-). Прежде всего, данные могут быть выровнены по -разному в зависимости от архитектуры. Что если архитектура отличается с другой стороны? Также использование ключевых слов, таких как __packed, не портативно между различными компиляторами.

Лучшее, как я знаю, это использовать API, такой как PHP Pack/распаковка. Это делает код по -настоящему портативным без использования уродливых ключевых слов, таких как __packed.

Я не нашел никакого пакета/распаковки для C в сети, поэтому я написал свой собственный.

Например, чтобы распаковать два слова из бинарных данных:

   pbuf_unpack(p_bts, "ww", &hdr, &ver); 

Где

   p_bts is binary data
   "ww" describes the data structure
   hdr and ver is where to put the datause an API like the PHP pack/unpack. 

Еще один более обширный пример:

   pbuf_unpack(p_entry, "bbbbbbbbww",
      &atrb_mbr.def_boot_par, &atrb_mbr.head_start, &atrb_mbr.sec_start,
      &atrb_mbr.cyl_start, &atrb_mbr.type, &atrb_mbr.head_end, 
      &atrb_mbr.sec_end, &atrb_mbr.cyl_end, &atrb_mbr.start_sec_pbr,
      &atrb_mbr.sec_per_par);

Упаковка очень проста:

   pbuf_pack(boot_buf, "sdsdhbhbhhbhhhwwbbbwsdsd", sizeof(fat_jmp_boot_t), 
      boot.jmp, sizeof(fat_oem_nm_t), boot.oem_nm, boot.n_bps, boot.n_spc, 
      boot.n_rs, boot.n_fs, boot.n_rde, boot.n_ts16, boot.media_des, 
      boot.n_fatsz16, boot.n_spt, boot.n_hds, boot.n_hs, boot.n_ts32, 
      boot.drv_no, boot.rsrvd1, boot.boot_sig, boot.vol_id, 
      sizeof(fat_vol_lbl_t), boot.lbl, sizeof(fat_vol_type_t), boot.type);

Он не только создает портативный код, но и красиво;)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top