c++ - 使用 istream 从 boost::asio UDP 套接字中检索 float

标签 c++ sockets boost udp boost-asio

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 没有任何意义?

enter image description here

最佳答案

这可能是由于字节顺序问题。以下类型的代码在使用

进行测试时有效
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/

相关文章:

objective-c - 从 Stream 获取套接字

c# - 使用二进制协议(protocol)的 TCP 成帧

c++ - 使用 boost::geometry::within 编译错误

c++ - 使用 firebreath 插件防止浏览器关闭

linux - Perl 套接字如何在 Linux 下解析主机名?

c++ - 无法找到请求的 Boost 库 Windows Cmake

c++ - 在 X11 窗口上移动窗口事件

c++ - 两次调用 pthread_join() 时 glibc pthread_join 崩溃

c++ - fatal error : QtGui/QApplication: No such file or directory|

c++ - IWebbrowser2 IE=edge 和用户代理字符串