Прежде всего, вы пропускаете знак &
перед coord_struct
в вызове на recvfrom
. Во-вторых ...
Правильный способ отправки двоичных данных по сети - преобразовать все в порядковый номер сети (big endian) при отправке и обратно в порядковый номер хоста при получении.
Отправка в Python:
lat = 14.566545
lon = 13.435456
alt = 3.5657732
coord_struct = struct.pack('!fff', lat, lon, alt)
# Notice the ! sign for network endianness.
udp_sock.sendto(coord_struct, (UDP_IP, UDP_PORT_SEND))
Получение в C:
struct coords {
float latitude;
float longitude;
float altitude;
};
struct coords coord_struct;
ssize_t recv_len;
// Assuming you have already correctly initialized the socket.
errno = 0;
recv_len = recvfrom(udp_fd, &coord_struct, sizeof(coord_struct), 0, (struct sockaddr*) &si_other, &si_slen);
// IMPORTANT ---------------^ notice the & here.
if (errno) {
// There was an error with recvfrom, print it to
// stderr to see what's wrong.
perror("recvfrom failed");
exit(1);
}
// Also check recv_len here, if recv_len < sizeof(coord_struct) you need
// to retry everything or try receiving more data.
// Convert from network endian to host endian:
coord_struct.latitude = ntohl((uint32_t)coord_struct.latitude );
coord_struct.longitude = ntohl((uint32_t)coord_struct.longitude);
coord_struct.altitude = ntohl((uint32_t)coord_struct.altitude );
printf(
"lat: %f; lon: %f; alt: %f\n",
coord_struct.latitude,
coord_struct.longitude,
coord_struct.altitude
);
Кроме того, вы также можете использовать MSG_WAITALL
при вызове recvfrom
, чтобы иметь меньше шансов получить меньше данных, чем ожидалось,Даже если структура, которую вы отправляете, не должна вызывать особых проблем, поскольку она очень мала и в основном всегда помещается в одну дейтаграмму UDP.