网络数据打包

时间:2011-09-10 20:18:46

标签: c++ networking packets packing

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

我也看到它被用于商业应用。所以我决定尝试一下,但结果并不是我的预期。

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

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

  3. 上述教程中的代码段:

        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字节长

3 个答案:

答案 0 :(得分:3)

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

我不会在那篇文章中放置过多的信任;除了你的异议,代码包含一个明显的错误。 Buffer只有3个元素长,但代码将数据存储在4个元素中。

答案 1 :(得分: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 <&lt;&lt; 28)到4294967295((1&lt; 32)-1)的无符号值将需要5个字节而不是4个字节的标准固定4-字节打包。

答案 2 :(得分:2)

  1. 打包的另一个原因是强制执行一致的结构,以便一台机器写入的数据可以被另一台机器可靠地读取。

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