Linux网络编程入门 互动版

在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器

在学习网络编程前,我们需要先了解下主机字节序和网络字节序

1.字序排列

以32位操作系统为例,一个32位整数由4个字节组成,在不同的CPU中,4字节整数值在内存空间的保存方式是不同的。

比如4字节整数值1可用二进制表示如下:

00000000 00000000 00000000 00000001

有的CPU按照上述顺序保存,即:

00000000 00000000 00000000 00000001

而有的CPU按照倒序保存,即:

00000001 00000000 00000000 00000000

因此,根据字节在内存中排列的顺序不同,将字节序分为主机字节序和网络字节序。

2.主机字节序

主机字节序,又称为小端字节序,是指整数的高位字节存储在内存的高地址处,而低位字节存储在内存的低地址处。 对应关系:

高位字节 -> 高地址

低位字节 -> 低地址

在32位操作系统,一个4字节整数0x12345678(16进制表示),内存布局如下:

内存地址: |1000 | 1001 | 1002 | 1003|

整数布局: |0x78 | 0x56 | 0x34 | 0x12|

其中1000,1001,1002,1003表示从低到高的内存地址,即1000是内存低地址,而1003是内存高地址。

0x12是整数的高位,根据上述对应关系,放在内存高地址,即1003,以此类推。

3.网络字节序

网络字节序,又称为大端字节序,是指整数的高位字节存储在内存的低地址处,而低位字节存储在内存的高地址处。 网络字节序正好是主机字节序的倒序。 对应关系:

高位字节 -> 低地址

低位字节 -> 高地址

在32位操作系统,一个4字节整数0x12345678(16进制表示),内存布局如下:

内存地址: |1000 | 1001 | 1002 | 1003|

整数布局: |0x12 | 0x34 | 0x56 | 0x78|

0x12是整数的高位,根据上述对应关系,放在内存低地址,即1000,以此类推。

4.总结

主机字节序:现代PC机大多采用小端字节序,因此小端字节序又称为主机字节序。Inter和AMD系列的CPU都采用小端序。

网络字节序:根据其含义可知,网络传输中的字节序,网络协议中使用网络字节序来进行传输。

当数据传输到不同字节序的主机之间,接收端收到数据必然会解析出现错误,因此需要做到字节序的统一。 解决的方法: 发送端将发送的数据转化为网络字节序发送------>接收端根据自身采用的字节序,解析收到的数据。

下面写程序判断下机器是采用主机字节序还是网络字节序。

#include <stdio.h>

union
{
    short value;
    char union_bytes[ sizeof(short) ];
} union_number;

int main()
{
    union_number.value = 0x0102;
    if ( (union_number.union_bytes[0] == 0x01) && (union_number.union_bytes[1] == 0x02)) {
        printf("这是网络字节序\n");
    } else if ( (union_number.union_bytes[0] == 0x02) && (union_number.union_bytes[1] == 0x01)) {
        printf("这是主机字节序\n");
    } else {
        printf("未知\n");
    }

    return 0;
}

第1行引入头文件stdio.h。stdio.h是C语言输入输出流(input/output)相关的,printf函数的头文件。

第3~7行定义了一个联合体,包括2字节的value以及2字节的union_bytes数组,根据联合体的定义,value和char数组共享同一块内存(比喻:一个房间,value和union_bytes共同拥有)。 我们知道判断主字节序和网络字节序的区别就是字节在内存中排列的顺序不同,一个正序一个倒序。 因此设计一个联合体,对value进行赋一个short值后,那么可以根据union_bytes判断该short值的高位字节是放在内存低地址还是高地址。

第11行对value赋值0x0102,即二进制00000001 00000010,此时根据联合体的特性,union_bytes的值也是0x0102

第12行判断高位字节(即0x01)位于内存低地址,低位字节(0x02)位于内存高地址,因此为网络字节序。

第14行判断高位字节(即0x01)位于内存高地址,低位字节(0x02)位于内存低地址,因此为主机字节序。

在右侧建立个c文件,试编写上述判断字节序类型的程序。