Ann*_*inn 68 c++ networking stl endianness
根据我的理解,字节顺序是组成多字节字的字节顺序不同,至少在最典型的情况下.这样一个16位整数可以存储为0xHHLL
或者0xLLHH
.
假设我没有那个错误,我想知道的是,当Endian可能会或可能没有不同的两台计算机之间发送信息时,Endianness何时成为主要因素.
如果我以char数组的形式传输1的短整数并且没有校正,它是否被接收并解释为256?
如果我使用以下代码分解并重新组合短整数,那么字节序不再是一个因素吗?
// Sender:
for(n=0, n < sizeof(uint16)*8; ++n) {
stl_bitset[n] = (value >> n) & 1;
};
// Receiver:
for(n=0, n < sizeof(uint16)*8; ++n) {
value |= uint16(stl_bitset[n] & 1) << n;
};
Run Code Online (Sandbox Code Playgroud)提前致谢!
Ker*_* SB 50
非常抽象地说,字节序是将变量重新解释为char数组的属性.
实际上,这对于您read()
来自write()
外部字节流(如文件或套接字)来说非常重要.或者,再次抽象地说,当序列化数据时,字节序很重要(主要是因为序列化数据没有类型系统,只是由哑字节组成); 和字节顺序也没有关系中的编程语言,因为语言只能对值,而不是表示.从一个到另一个是您需要深入细节的地方.
写作:
uint32_t n = get_number();
unsigned char bytesLE[4] = { n, n >> 8, n >> 16, n >> 24 }; // little-endian order
unsigned char bytesBE[4] = { n >> 24, n >> 16, n >> 8, n }; // big-endian order
write(bytes..., 4);
Run Code Online (Sandbox Code Playgroud)
在这里我们可以说,reinterpret_cast<unsigned char *>(&n)
并且结果将取决于系统的字节顺序.
阅读:
unsigned char buf[4] = read_data();
uint32_t n_LE = buf[0] + buf[1] << 8 + buf[2] << 16 + buf[3] << 24; // little-endian
uint32_t n_BE = buf[3] + buf[2] << 8 + buf[1] << 16 + buf[0] << 24; // big-endian
Run Code Online (Sandbox Code Playgroud)
再次,在这里我们可以说,uint32_t n = *reinterpret_cast<uint32_t*>(buf)
并且结果将取决于机器的字节序.
正如您所看到的,如果使用代数输入和输出操作,使用整数类型,您永远不必知道自己系统的字节序,只知道数据流的字节序.对于其他数据类型double
,问题更复杂.
Joh*_*0te 35
为了记录在案,如果你的设备之间传输数据,你应该几乎总是使用网络字节顺序有ntohl
,htonl
,ntohs
,htons
.无论您的系统和目标系统使用什么,它都将转换为Endianness的网络字节顺序标准.当然,两个系统应该像这样编程 - 但它们通常在网络场景中.
不,虽然你确实有正确的总体想法.你所缺少的是这样的事实,即使它通常是串行连接,网络连接(至少大多数网络连接)仍然保证八位字节(字节)级别的正确字节顺序 - 即,如果你发送一个带有值的字节在小端机器上的0x12,它仍然会在大端机器上被接收为0x12.
看一下,如果你看一下十六进制的数字,它可能会有所帮助.它从0x0001开始.你将它分成两个字节:0x00 0x01.收到后,它将被读为0x0100,结果为256.
由于网络处理八位字节级别的字节序,因此通常只需要补偿字节的顺序,而不是字节内的位.
可能最简单的方法是在发送时使用htons/htonl,在接收时使用ntohs/ntohl.当/如果这还不够时,有许多替代方案,如XDR,ASN.1,CORBA IIOP,Google协议缓冲区等.
补偿的"标准方式"是"网络字节顺序"的概念已被定义,几乎总是(AFAIK)作为大端.
发送者和接收者都知道有线协议,如果需要,将在发送之前和接收之后进行转换,以便为应用程序提供正确的数据.但这种转换发生在您的网络层内,而不是您的应用程序中.
这两个结尾都有一个我所知道的优势:
unsigned int*
但是你知道存储的值是<256,你可以将指针转换为unsigned char*
.Endianness总是一个问题.有人会说,如果你知道连接到网络的每个主机运行相同的操作系统等,那么你就不会有问题.这是真的,直到它不是.您始终需要发布详细说明在线数据的EXACT格式的规范.它可以是您想要的任何格式,但每个端点都需要了解格式并能够正确解释它.
一般来说,协议使用big-endian来表示数值,但是如果每个人都不兼容IEEE 754等,这就有局限性.如果你可以节省开销,那么使用XDR(或你最喜欢的解决方案)并保证安全.
归档时间: |
|
查看次数: |
7430 次 |
最近记录: |