如何将网络数据反序列化为不同的原语?

时间:2010-11-16 21:45:17

标签: c++ sockets networking

我确信在进行任何类型的网络编程(或带文件的I / O)时这是一个非常常见的操作,但我找不到答案。

基本上我有一个来自网络的数据报包,它有一系列单精度浮点数(每个4个字节)。

我编写了一些从套接字读取的基本网络代码,并将数据存储到缓冲区中,该缓冲区声明如下:

char buffer[24];

这是我的反序列化代码:

for (int i=0; i<6; i++) {
    float *pf = reinterpret_cast<float*>(buffer + i*sizeof(float));
    printf("%f\n", *pf);
}

但它会导致我的程序崩溃。

如果有人能指点我这方面的好教程,即管理,存储和解释数据,我真的很感激!我看了,但我不知道该搜索什么。

3 个答案:

答案 0 :(得分:1)

你有一个24字节的缓冲区,但你可以在24 * sizeof(float)个字节上运行,这还有很多。

char buffer[24 * sizeof(float)];

答案 1 :(得分:0)

请参阅 ntohs()和朋友。

答案 2 :(得分:0)

如果他们真的发送浮动 - 我不建议,如果你有选择 - 那么你必须做一些hackery。

这是我写的一个实用程序库来做这种事情。它适用于Windows(MSVC)和Linux(GCC)。它可能不适用于其他平台!使用风险自负。

/**************  UTILITY ******************************/
template<class Val> Val ntohx(const Val& in)
{
    char out[sizeof(in)] = {0};
    for( size_t i = 0; i < sizeof(Val); ++i )
        out[i] = ((char*)&in)[sizeof(Val)-i-1];
    return *(reinterpret_cast<Val*>(out));
}

template<> uint16_t ntohx<uint16_t>(const uint16_t & v)
{
    return ntohs(v);
}

template<> uint32_t ntohx<uint32_t>(const uint32_t & v)
{
    return ntohl(v);
}

template<> uint64_t ntohx<uint64_t>(const uint64_t & v)
{
    uint32_t ret [] =
    {
        ntohl(((const uint32_t*)&v)[1]),
        ntohl(((const uint32_t*)&v)[0])
    };
    return *((uint64_t*)&ret[0]);
}
template<> float ntohx<float>(const float& v)
{
    uint32_t const* cast = reinterpret_cast<uint32_t const*>(&v);
    uint32_t ret = ntohx(*cast);
    return *(reinterpret_cast<float*>(&ret));
}

template<class Val> bool ieee_isnan(const Val& val)
{
    // According to the IEEE Standard for floating-point numbers, 
    // NaNs have the interesting attribute of always returning
    // false in comparisons; even to themselves.
    // All platforms we currently support use IEEE floating points,
    // so this should work. [Dib]
    return val != val;
};