代码之家  ›  专栏  ›  技术社区  ›  lmirosevic

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

  •  0
  • lmirosevic  · 技术社区  · 14 年前

    我相信这是一个非常常见的操作时,做任何类型的网络编程(或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 回复  |  直到 14 年前
        1
  •  0
  •   John Dibling    14 年前

    如果他们是 真正地 发送浮动——如果你有选择的话,我不建议这样做——那么你必须做一些黑客操作。

    这里有一个实用程序库,我写的只是做这种事情。它在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;
    };
    
        2
  •  1
  •   Loki Astari    14 年前

    你有一个24字节的缓冲区 24 * sizeof(float) 字节,这是相当多的。

    char buffer[24 * sizeof(float)];
    
        3
  •  0
  •   user207421    14 年前

    ntohs() 还有朋友。