Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过UDP发送浮点结构_Python_C_Struct_Floating Point_Udp - Fatal编程技术网

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
时,它工作得很好!