tl;dr 我无法从使用 boost asio UDP 套接字接口(interface)填充的 boost::streambuf 创建的 istream 中读取 float 。我的数据似乎已损坏或处理不当。
我目前正在编写一个将实现 DIS(分布式交互式模拟)协议(protocol)的接口(interface)。我正在使用 boost::asio 库打开 UDP 套接字并接收数据。我正在将数据从网络中拉出并正确地放入 streambuf,但我无法读取 float 。
套接字代码:
boost::asio::streambuf streamBuf;
boost::asio::streambuf::mutable_buffers_type buf = streamBuf.prepare(maxSize);
udp::endpoint senderEndpoint;
size_t packetLength;
try {
packetLength = sock.receive_from(buf, senderEndpoint);
streamBuf.commit(packetLength);
} catch(boost::system::system_error se) {
std::cout << "ERROR: " << se.what() << std::endl;
}
std::istream stream(&streamBuf);
从istream中读取的代码
float readFloat32(std::istream& stream) {
float ret;
stream.read((char*)&ret, sizeof(float));
return ret;
}
double readFloat64(std::istream& stream) {
double ret;
stream.read((char*)&ret, sizeof(double));
return ret;
}
现在我为我需要的每种数据类型编写了类似的函数(主要是 uint8_t - uint32_t)。
解析 PDU
//--Entity ID
entityState.entityID.siteID = readUInt16(stream);
entityState.entityID.appID = readUInt16(stream);
entityState.entityID.entityID = readUInt16(stream);
...etc, etc.
//--Entity Linear Velocity
entityState.entityLinearVelocity.x = readFloat32(stream);
entityState.entityLinearVelocity.y = readFloat32(stream);
entityState.entityLinearVelocity.z = readFloat32(stream);
...etc, etc.
我试图解析的数据看起来像最后的照片。我可以很好地解析所有内容,但是当我到达由 3 个 32 位 float 组成的“实体线速度” block 时,我的数据变得错误。使用 wireshark 我已经确认通过网络发送了正确的 btyestream。
对于我发送这一系列字节的速度:
42 74 aa 97 c2 80 b3 8f 42 e2 dc 54
相当于 61.166592、-64.350700 和 113.430328。但是,我的应用程序将其读取为
42 72 ffffffaa ffffff97 ffffffc2 ffffff80 ffffffb3 ffffff8f 42 ffffffe2 ffffffdc 54
我的 float 最终为 -1.10153e-24、-1.77004e-29 和 7.58951e+12。
有谁知道为什么我可以使用此实现读取各种大小的单位,但 float 没有任何意义?
最佳答案
这可能是由于字节顺序问题。以下类型的代码在使用
进行测试时有效std::string bin = {'\x42', '\x74', '\xaa', '\x97'};
std::istringstream raw(bin);
使用字节交换,即 ntohl
,
float readFloat32(std::istream& stream) {
union {
float fval;
uint32_t ival;
} ret;
stream.read((char*)&ret, sizeof(float));
ret.ival = ntohl(ret.ival);
return ret.fval;
}
添加字节交换后,readFloat
返回的值为61.1666
。
关于c++ - 使用 istream 从 boost::asio UDP 套接字中检索 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38315302/