我一直在寻找一种有效打包数据的方法,以便通过网络发送数据。 我找到了一个提出方法的主题:http://www.sdltutorials.com/cpp-tip-packing-data
我也看到它被用于商业应用。所以我决定尝试一下,但结果并不是我的预期。
首先,“打包”数据的重点是保存字节。但我认为上面提到的算法根本不会保存字节。 因为,没有打包......服务器会发送4个字节(数据),打包后服务器发送一个字符数组,长4个字节......所以这是没有意义的。
除此之外,为什么会有人添加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字节长
答案 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)
打包的另一个原因是强制执行一致的结构,以便一台机器写入的数据可以被另一台机器可靠地读取。
这不是“添加”;它正在执行按位-AND以屏蔽LSB(最低有效字节)。但这里看起来没必要。