欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

linux网路编程:字节序(大端、小端、网络、主机)

程序员文章站 2022-03-29 12:49:20
字节序:就是数据在内存中的存放顺序,也可称之为端模式。 大端模式和小端模式的定义 1) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。 2) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。 3) 网络字节序:TCP/I ......

字节序:就是数据在内存中的存放顺序,也可称之为端模式。

大端模式和小端模式的定义

1) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

2) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

3) 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序

什么是高位字节,低位字节?

一般一个16位(双字节)的数据,比如 FF1A (16进制),(4位二进制用一个十六进制表示)
那么高位字节就是FF,低位是1A
如果是32位的数据,比如 3F68415B
高位字(不是字节)是3F68
低位字是415B
右边是低位,左边是高位

include <stdio.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    unsigned int x = 0x12345678;
    unsigned char* p = (unsigned char*)&x;

    //小端字节序
    printf( "%p->%0x\n%p->%0x\n%p->%0x\n%p->%0x\n", p+0, *(p+0), p+1, *(p+1), p+2, *(p+2), p+3, *(p+3) );

    printf( "---------------------\n" );

    //h:主机字节序    n:网络字节序  l:long
    unsigned int y = htonl( x );    
    p = ( unsigned char* )&y;

    printf( "%p->%0x\n%p->%0x\n%p->%0x\n%p->%0x\n", p+0, *(p+0), p+1, *(p+1), p+2, *(p+2), p+3, *(p+3) );

    return 0;
}

输出结果:

0x7fff3bb55708->78
0x7fff3bb55709->56
0x7fff3bb5570a->34
0x7fff3bb5570b->12
---------------------
0x7fff3bb5570c->12
0x7fff3bb5570d->34
0x7fff3bb5570e->56
0x7fff3bb5570f->78

第一种结果:

0x7fff3bb55708->78
0x7fff3bb55709->56
0x7fff3bb5570a->34
0x7fff3bb5570b->12

地址从08--->0b属于增长,   08这个低地址放的是78, 78这个数是低位字节,  这种情况属于低地址放低位字节,高地址放高位字节, 所以叫:小端字节序

第二种结果:

0x7fff3bb5570c->12
0x7fff3bb5570d->34
0x7fff3bb5570e->56
0x7fff3bb5570f->78

把主机字节序转换成了网络字节序, 这种情况属于低地址放高位字节,高地址放低位字节,所以叫:大端字节序

---------------------------------------------------------------------------------------------------------------------------------------------------------

字节序转换相关API:

htonl:主机字节序转换成网络字节序

inet_addr:函数原型:in_addr_t inet_addr(const char *cp)

作用:把ip地址格式转成网络字节序

unsigned int addr = inet_addr( "192.168.1.100" );
printf( "%u\n", addr );
printf( "0x%0x\n", addr );

结果:

1677830336
0x6401a8c0

这两个数是一样的

ntohl: 网络字节序转主机字节序

unsigned int haddr = ntohl( addr );
printf( "%u\n", haddr );
printf( "0x%0x\n", haddr );

inet_ntoa:网络字节序,转ip地址格式

struct in_addr ipaddr;
ipaddr.s_addr = addr;
printf( "%s\n", inet_ntoa( ipaddr ) );