【发布时间】:2017-09-06 08:50:49
【问题描述】:
我无法理解“网络字节顺序”的概念。我已阅读 Network byte order and endianness issues,但仍然无法阅读。
现在,我对两台计算机之间通过 TCP 套接字进行的通信进行了正式的网络协议描述。这是短语“...使用 little-endian 字节顺序”。但是标准的网络字节顺序是大端的。
我是否应该考虑字节顺序,如果在网络的两侧都完全定义了字节顺序,并且我写了,粗略地说,void* 和 size?网络如何“知道”我的数据?浮点类型呢?
例如,我是否不能侧写:
stream.setDevice(tcpSocket);
stream.setByteOrder(QDataStream::LittleEndian);
...
struct SomeType
{
int32_t a;
int32_t b;
double c;
friend QDataStream& operator << (
QDataStream& stream, const SomeType& x)
{
stream << x.a
<< x.b
<< x.c;
return stream;
}
};
或者可能只是:
SomeType x;
tcpSocket.write(&x, size); // If known a byte order and a data structure alignment on both sides
【问题讨论】:
-
您计算机中的“网络”或网络堆栈对您传输的数据一无所知,它只是来回传递二进制 blob 序列。当您必须将数据解释为您的程序可以处理的东西时,问题就出现在您的程序中。如果一个 big-endian 系统将未经修改的
int发送到另一个恰好是 little-endian 的系统,那么接收者会认为接收到的int值不是发送的。 -
@Someprogrammerdude ,我可以在我的示例中不考虑这一点(如果知道主机端的字节顺序和数据结构对齐)?
-
@VladimirBershov 你可以,但有一天这个错误会成为一个问题。在任何情况下,您都会看到使用压缩成帧协议的性能和维护优势。 google 的协议缓冲区就是这样一种免费提供的协议。
-
您的代码在具有不同架构的 2 台机器(例如 x86 little endian 和 arm big endian)上运行时会立即中断。两种变体,因为
ints 将有不同的表示。第二个版本甚至可能在不同的编译器版本之间中断,因为他们可能对结构布局(对齐等)有不同的理解。 -
@VladimirBershov 这并不能解决当字节序列 0x00000001 通过网络传输时机器可能将其解释为 1 而另一个解释为 2^24 的问题。避免这种情况的唯一方法是使用适当的序列化,它独立于平台工作。
标签: c++ qt tcp network-programming endianness