整理了一下网络上关于字节序的描述和自己的理解。
小端字节序
简单的说就是:低字节存储在起始地址指向的地方。
比如:
short int 0xaabb
在小端的系统中存储方式是(假设地址从0开始):
地址 | 0 | 1 |
---|---|---|
数据 | 0xbb | 0xaa |
大端字节序
就是高字节存储在起始地址指向的地方。
同样一个short int 0xaabb
在大端的系统中存储方式是:
地址 | 0 | 1 |
---|---|---|
数据 | 0xaa | 0xbb |
那么我们在网络编程的时候,为什么以及在什么情况下需要字节序转换呢?
若不进行字节序转换时:
同样一个short int 0xaabb由PC1经网络(网络字节序是大端)传输至PC2时
PC1:大端 地址 | 0 | 1 | 实际值 |
---|---|---|---|
数据 | 0xaa | 0xbb | 0xaabb |
net:大端 字节号 | 0 | 1 | 实际值 |
数据 | 0xaa | 0xbb | 0xaabb |
PC2:大端 地址 | 0 | 1 | 实际值 |
数据 | 0xaa | 0xbb | 0xaabb |
当一台PC是小端,一台PC是大端时:
PC1:小端 地址 | 0 | 1 | 实际值 |
---|---|---|---|
数据 | 0xbb | 0xaa | 0xaabb |
net:大端 字节号 | 0 | 1 | 实际值 |
数据 | 0xbb | 0xaa | 0xbbaa |
PC2:大端 地址 | 0 | 1 | 实际值 |
数据 | 0xbb | 0xaa | 0xbbaa |
从这个例子就可以看出,为什么需要字节序转换了。可以理解为:虽然在内存中存储的方式是一样的,但是大端和小端系统对其进行了不同的解析,导致实际值变了。
若两个pc都是小端呢,会不会解析错误呢?
答案是不会的。
但是更加严谨的办法是,在网络编程中,只要使用了short,int,long这种超过一个字节的变量,那么就需要用hton函数来进行字节序转换,同样的接收方需要用ntoh来转换字节序。
之前一直困扰我的是,如果一个结构体:
struct c{
char a;
char b;
}
传输这样一个结构体c的时候需不需进行字节序转换,在理解了其在内存中存储的方式没变,以及不管是大端还是小端的机器,都是从低地址进行操作的之后,我们很容易的得出,是不需要的。