Python 通过UDP发送浮点结构
因此,我在Python 通过UDP发送浮点结构,python,c,struct,floating-point,udp,Python,C,Struct,Floating Point,Udp,因此,我在Python中有一个浮点数结构,我通过UDP发送它: lat = 14.566545 lon = 13.435456 alt = 3.5657732 coord_struct = struct.pack('fff', lat, lon, alt) udp_sock.sendto(coord_struct,(UDP_IP,UDP_PORT_SEND)) 对于用C编写的程序,它应该接收结构并使用它: typedef struct coords{ float lati
Python
中有一个浮点数结构,我通过UDP
发送它:
lat = 14.566545
lon = 13.435456
alt = 3.5657732
coord_struct = struct.pack('fff', lat, lon, alt)
udp_sock.sendto(coord_struct,(UDP_IP,UDP_PORT_SEND))
对于用C
编写的程序,它应该接收结构并使用它:
typedef struct coords{
float latitude;
float longitude;
float altitude;
} GEO_POS;
GEO_POS coord_struct;
recv_len = recvfrom(udp_fd, coord_struct, sizeof(coord_struct), 0, (struct sockaddr*) &si_other, &si_slen);
printf("lat: %f; lon: %f; alt: %f", coord_struct.latitude, coord_struct.longitude, coord_struct.altitude);
但是接收到的数据是错误的,例如:47.88980
作为54698924740000000000000
接收
我是否需要序列化结构
才能发送它,如果需要,如何发送
有更好的方法吗
谢谢你的帮助 首先,在调用
recvfrom
时,您在coord_struct
前面缺少一个&
符号。其次
通过网络发送二进制数据的正确方法是在发送时将所有内容转换为网络端(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
);
struct-coords{
浮动纬度;
浮动经度;
漂浮高度;
};
结构坐标系坐标系;
重新登记;
//假设您已经正确初始化了套接字。
errno=0;
recv_len=recvfrom(udp_fd,&coord_struct,sizeof(coord_struct),0,(struct sockaddr*)&si_other,&si_slen);
//重要提示----------------^请注意此处的(&H)。
如果(错误号){
//recvfrom出现错误,请将其打印到
//去看看出了什么问题。
perror(“recvfrom失败”);
出口(1);
}
//如果recv_len
此外,在调用
recvfrom
时,您可能还希望使用MSG_WAITALL
,以减少接收数据量低于预期的机会。尽管您发送的结构应该不会造成太大的麻烦,因为它非常小,基本上总是适合单个UDP数据报。我在这里看到的第一个问题是,C中的coords
结构被定义为由三个real64
变量组成。如果该64
代表64位(因此基本上是一个double
),那就是一个问题:struct.pack
的f
说明符意味着32位浮点
,而不是64位。您应该在问题中添加real64
的定义。Ok不知道f指定了32位浮点。对于测试,我也可以在C程序中使用float-on。然后用real64试试。另一个问题是,通过网络发送数据通常需要将所有内容转换为网络端(即big-endian),然后在接收时返回到所需的端。如果这些程序在具有不同endianness的不同机器上运行,将导致接收到错误的值。转换使用htonl/htons
进行发送,使用ntohl/ntohs
进行接收,并使用struct.pack
的code>说明符(例如!f
)。噢,似乎struct.pack
还有很多内容,我想,谢谢!我完全忘记了字节顺序,我查了一些示例代码,他们也没有使用,所以我忘了。我会试一试的。嗯,很遗憾,我仍然收到一些胡言乱语。非常感谢!它现在正在工作,真不敢相信这是一个如此简单的错误。当我使用ntohl
时,我只保留整数值(带和不带uint32\u t
),但当我不使用ntol
时,它工作得很好!