В вашем коде есть некоторые ошибки:
На передающей стороне вы неправильно выполняете арифметику указателя c при назначении указателя body_ptr
. Поскольку header_ptr
объявлен как CommandHeader_t*
, выполнение (header_ptr + sizeof(CommandHeader_t))
будет вычислять адрес памяти, который равен sizeof(CommandHeader_t)
количеству CommandHeader_t
элементов после адреса, на который указывает header_ptr
. Это не то, что вам нужно. Вместо этого вам нужно вычислить адрес, который равен sizeof(CommandHeader_t)
количеству char
s после адреса header_ptr
.
Итак, вам нужно изменить это:
char* body_ptr = (char*) (header_ptr + sizeof(CommandHeader_t));
На это вместо этого:
char* body_ptr = ((char*) header_ptr) + sizeof(CommandHeader_t);
Более простой способ справиться с этим - добавить член char[1]
к CommandHeader_t
, а затем вычесть 1, когда он malloc()
, например:
#pragma pack(push, 1) // or equivalent
struct CommandHeader_t {
int BodySizeByte;
char data[1];
};
#pragma pack(pop) // or equivalent
CommandHeader_t* header_ptr = (CommandHeader_t*) malloc(offsetof(CommandHeader_t, data) + BODY_SIZE_BYTE);
header_ptr->BodySizeByte = BODY_SIZE_BYTE;
char* body_ptr = header_ptr->data;
snprintf(body_ptr, BODY_SIZE_BYTE, "Hello World");
Кроме того, поскольку вы используете SOCK_DGRAM
на отправляющей стороне, sendto()
ориентирован на сообщения, отправляя все данные в 1 сообщении. Но ваш принимающий код написан так, как будто вместо этого он использует потоковый сокет. Не допускайте такого несоответствия типов сокетов. Если вы хотите вызвать recv()
несколько раз, используйте поточно-ориентированный сокет с обеих сторон. В противном случае используйте сокет, ориентированный на сообщения, с обеих сторон, а затем попросите получателя выделить буфер, достаточно большой для приема всего сообщения размером 1 recvfrom()
(вы можете использовать ioctl(FIONREAD)
, чтобы определить размер следующего ожидающего сообщения), а затем проанализируйте содержимое этого сообщения по мере необходимости.
Кроме того, ваш получатель пропускает буфер body_ptr
, выделенный им с помощью malloc()
.