我正在使用Winsock API开发网络应用程序。每当我测试应用程序发送一些字节时,例如在数组中:
char[0] = '1';
char[1] = '2';
char[2] = '3';
char[3] = '4';
char[4] = '\0';
我使用send和recv套接字来接收在localhost上运行的另一个应用程序上的字节,然后字节顺序似乎根本没有改变。是因为我在localhost服务器上测试它吗?网络字节顺序是否会改变为:
char[0] = '\0';
char[1] = '4';
char[2] = '3';
char[3] = '2';
char[4] = '1';
如果我通过互联网收到它?
答案 0 :(得分:2)
8位字符数组和字符串不会受到网络字节顺序问题的影响。由于数组中的每个单独的char已经按顺序排列,并且使用数组中的下一个char字节进行排序...这是受影响的short,int和long。
此外,进行任何字节交换的不是send和recv调用。字节交换与处理器如何在内存中布局整数有关:
要了解字节顺序问题,请考虑英特尔芯片上的以下代码:
// code that demonstrates how integer values are laid out in memory
int msg = 0x01020304;
char* buffer = (char*)&msg;
for (int x = 0; x < 4; x++)
printf("%d %d %d %d\n", buffer[0], buffer[1], buffer[2], buffer[3]);
打印出的结果是:
4 3 2 1
这表明x86处理器按照您可能期望的相反顺序排列整数的内存字节。最低有效字节或整数首先在内存中排序。这是Little Endian。
在旧的Sun工作站等Sparc芯片上打印出相同的代码:
1 2 3 4
这是Big Endian。
只有当您将数据写入磁盘或网络时,内存序列的字节顺序才会重要。一旦另一台计算机读取另一台计算机写出的字节序列,那么读取整数的CPU将根据它自己的字节序来解释它。
字节顺序通常在将整数写入文件或流式传输到网络时很重要。如果没有应用程序开发人员的转换,传递给send()的原始缓冲区就会在处理器将字节输出到内存中时完全传输。有关从Big Endian(也称为网络字节顺序)转换整数和短路的更多详细信息,请参阅htonl和朋友。
答案 1 :(得分:1)
当您查看字节流并决定解释数据时,字节顺序才会发挥作用。
例如,如果你有字节流:
'1' '2' '3' '4' '0'
然后你决定将数据解释为一个字符流,然后假设每个字符有一个字节,你就得到一个包含字符串“1234”的数组。
但是,如果您决定将数据解释为int
,那么字节顺序将起作用,因为您有多个字节用于编码数据类型(int)。上述流的值具有十六进制值:
0x31 0x32 0x33 0x34 0x00
(0x31是十进制值'1'等)
这是字节序发挥作用的地方。您需要知道流中数据的字节顺序,以便在反序列化时可以将其成功转换回正确的值。