1

我正在寻找一种方法来有效地打包我的数据,以便通过网络发送它们。我找到了一个建议方法的主题:http ://www.sdltutorials.com/cpp-tip-packing-data

而且我还看到它被用于商业应用。所以我决定试一试,但结果并不如我所愿。

  1. 首先,“打包”数据的全部意义在于节省字节。但我认为上面提到的算法根本没有节省字节。因为,没有打包...服务器会发送4个字节(数据),打包后服务器会发送一个字符数组,4个字节长...所以没有意义。

  2. 除此之外,为什么有人会添加 0xFF ,它根本没有做任何事情。

上面提到的教程中的代码片段:

    unsigned char Buffer[3];
    unsigned int Data = 1024;
    unsigned int UpackedData;
    Buffer[0] = (Data >> 24) & 0xFF;
    Buffer[1] = (Data >> 12) & 0xFF;
    Buffer[2] = (Data >> 8) & 0xFF;
    Buffer[3] = (Data ) & 0xFF;
    UnpackedData = (Buffer[0] << 24) | (Buffer[1] << 12) | (Buffer[2] << 8) | (Buffer[3] & 0xFF);

结果:0040 // 4 字节长字符 1024 // 4 字节长

4

3 回答 3

3

& 0xFF是为了确保它在 0 到 255 之间。

我不会太相信那个帖子。除了您的反对之外,该代码包含一个明显的错误。Buffer只有 3 个元素长,但代码将数据存储在 4 个元素中。

于 2011-09-10T20:25:23.837 回答
3

对于整数,我发现通常有用的一种简单方法是 BER 编码。基本上对于一个无符号整数,您为每个字节写入 7 位,使用第 8 位来标记是否需要另一个字节

void berPack(unsigned x, std::vector<unsigned char>& out)
{
    while (x >= 128)
    {
        out.push_back(128 + (x & 127)); // write 7 bits, 8th=1 -> more needed
        x >>= 7;
    }
    out.push_back(x); // Write last bits (8th=0 -> this ends the number)
}

对于有符号整数,您将符号编码为最低有效位并使用与以前相同的编码

void berPack(int x, std::vector<unsigned char>& out)
{
    if (x < 0) berPack((unsigned(-x) << 1) + 1, out);
          else berPack((unsigned(x) << 1), out);
}

使用这种方法,小数字将使用更少的空间。另一个优点是这种编码已经是体系结构中立的(即数据将独立于系统的字节序被正确理解),并且相同的格式可以处理不同的整数大小,并且您可以将数据从 32 位系统发送到64 位系统没有问题(当然假设值本身没有溢出)。

付出的代价是,例如从 268435456 (1 << 28) 到 4294967295 ((1 << 32) - 1) 的无符号值将需要 5 个字节,而不是标准固定 4 字节打包的 4 个字节。

于 2011-09-10T20:32:44.363 回答
2
  1. 打包的另一个原因是强制执行一致的结构,以便一台机器写入的数据可以被另一台机器可靠地读取。

  2. 这不是“添加”;它正在执行按位与以屏蔽 LSB(最低有效字节)。但这里看起来没有必要。

于 2011-09-10T20:23:59.380 回答