弄清楚网络、hex和ascii是如何交互的
Figuring out how networking, hex, and ascii interact
我最近被分配到一个C++项目,该项目涉及通过UDP在计算机之间发送信息。当数据包到达时,我有一个程序可以接受数据并将其显示为原始十六进制字符串。然而,我很难准确地理解整个过程应该如何运作。据推测,十六进制字符串包含几个字段(例如,4个字符的数组、一些float_32s和一些uint_32s)。
如何将该字符串的部分转换为正确的变量类型?第一个值,ASCII标题,非常简单;十六进制字符串中的前八个字符是ASCII字的十六进制表示(0x45十六进制可以直接转换为大写字母E)。但是下一个值,32位浮点,对我来说并没有什么意义。十六进制值"42 01 33 33"和浮点值"32.3"之间的关系是什么?
我有点不知所措,我觉得我错过了一些关于数字系统工作方式的重要信息。
C中的所有类型都有一个表示(对于大多数类型,它是由特定的实现定义的)。大多数C实现使用IEEE 754来表示浮动类型(这实际上可能是C和C++的要求,但从内存来看不是)。维基百科的文章解释了浮动类型是如何在内存中表示的。在大多数C和C++实现中,float
是32位类型,double
是64位类型。因此,在这些实现中,float
是4字节宽,而double
是8字节宽。
请小心,因为字节顺序可能不同。有些体系结构将浮动类型存储在小端序中,有些存储在大端序中。维基百科上也有一篇关于endianness的文章。
要将字节复制到浮动类型,必须确保浮动类型的大小与您拥有的字节数相同,然后才能逐个复制字节‘进入&rsquo的;浮动型。像这样的东西会给你它的要点:
unsigned char rep[] = { 0x42, 0x01, 0x33, 0x33 };
float someFloat;
if (sizeof(someFloat) == 4)
{
memcpy(&someFloat, rep, sizeof(someFloat));
}
else
{
// throw an exception or something
}
还有其他方法可以将字节复制到浮动类型,但要小心‘违反规则;(键入punning等)。此外,如果结果值不正确,可能是因为字节顺序错误,因此您需要反向复制字节,以便表示中的第4个字节是浮点的第1个字节。
如果您有一个十六进制值:
42 01 33 33
它相当于
0100 0010 0000 0001 0011 0011 0011 0011
二进制代码。
现在,有一个叫做IEEE754的浮点标准,它告诉你如何将浮点数格式化为二进制或反格式。
其要点是,第一位是符号(正/负数),接下来的8位是指数,最后的23位是尾数。这就是计算机内部保存浮点数的方式,因为它只能存储1和0。
如果你按照IEEE规定的方式把它们加在一起,你会得到32.3。
确切的数据格式由所使用的协议指定,但表示数字数据的常用方法有:
无符号整数:这实际上是最简单的。它的典型表示原理上与我们的普通十进制类似,只是"数字"是字节,可以有256个不同的值。
如果你看一个像3127这样的十进制数字,你会看到三位数字。最低有效位是最后一位(本例中为7)。最小有效性意味着,如果将其更改为1,则得到该值的最小更改(即1)。本例中最重要的数字是最左边的3:如果你把这个数字改成1,你就得到了值的最大变化,即1000的变化。由于有10个不同的数字(0到9),"3127"表示的数字是3*10*10*10+1*10*10+2*10+7。请注意,itz只是一个惯例,即最高有效数字优先;您也可以定义最低有效数字先出现,然后这个数字将被写为"7213"。
现在,在大多数编码中,无符号数字的工作原理完全相同,只是"数字"是字节,因此我们的基数不是10,而是256。此外,与十进制不同,无论最高有效字节(MSB)还是最低有效字节(LSB)先出现,都没有通用的约定;这两种约定都用于不同的协议或文件格式。
例如,在MSB优先的4字节(即32位)无符号int(也称为big-endian编码)中,值1000=0*256^3+0*256^2+3*256+232将由四字节值0, 0, 3, 232
或十六进制00 00 03 E8
表示。对于little-endian编码(首先是LSB),它将是E8 03 00 00
。作为16位整数,它将只是03 E8
(big-endian)或E8 03
(little-endian)。
对于有符号整数,最常用的表示法是2的补码。基本上,这意味着如果最高有效位是1(即最高有效字节是128或更大),字节序列不会像上面写的那样对数字进行编码,而是通过从中减去2^(位)得到的负数,其中(位)是数字中的位数。例如,在有符号的16位int中,序列FF FF
不是16位无符号int中的65535,而是65535-2^16=-1。与无符号整数一样,您必须区分大端序和小端序。例如,-3在16位字节序中是FF FD
,但在16位小字节序中却是FD FF
。
浮点比较复杂;今天通常使用IEEE/IEC规定的格式。基本上,浮点数的形式是符号*(1.尾数)*2^指数,符号、尾数和指数存储在不同的子字段中。同样,还有小端序和大端序形式。
- Qt VTK交互风格的信号到小部件
- Qt Quick-如何仅从c++代码与qml属性交互
- 复制和交换习惯用法与移动操作之间的交互
- 为什么在访问 vtkRenderWindow 的"交互器"变量时会发生段错误?
- Qt QGraphicsProxyWidget 与 QGraphicsScene 的交互
- 使用 Python 事件并与 C++ 交互
- 函数-本地枚举声明和 ADL 的交互
- 如何在扩展的QQuickItem中与模型交互
- 寻找C++中数组和cout交互的解决方案
- C++继承和"常量"交互的问题
- 以太坊与外部 c++ 库的交互稳定性
- 玩家移动和碰撞之间的交互问题
- C++ 和 Lua 函数之间的交互与 3D 矢量参数
- 内存分配究竟是如何发生的,Java和C如何交互以跟踪同一对象?
- 如何包装对象,使它们成为无法交互的单独类型?
- 通过交互器获取向量中的索引
- 如何在python中的PyArrow和C++中的Arrow之间进行交互时将PyArrow表转换为Arrow表
- 检测屏幕上的坐标是否可交互
- 如何在不中断整个循环的情况下跳过循环交互 - C++
- 使用 IDispatch::调用进行 OLE 交互的参数构造