c语言主机字节序和网络字节序

一、什么是字节序

字节序是指多字节数据在计算机内存中存储顺序,或者网络传输时各字节的传输顺序,字节序分为大端序和小端序。

  • 大端序:高字节存储在低位地址,传输数据时高位在前;
  • 小端序:低字节存储在低位地址,传输数据时高位在后;

假设0x4001-0x4004地址中存储有一个整型变量0x12345678,它在大端和小端mcu中的存储方式如下:

地址大端存储小端存储
0x40040x780x12
0x40030x560x34
0x40020x340x56
0x40010x120x78

地址0x4001是低位地址,0x12是数据的高位,高位数据0x12放在低位地址,则是大端序,反之则是小端序。

前面讲的都是多字节数据在计算机中存储的方式,我们在进行数据通讯的时候通常也会约定字节序。在数据通讯中,数据的高位先传输,则为大端序,数据的低位先传输,则为小端序。比如0x12345678这四个字节的数据,如果依次传输0x12、0x34、0x56、0x78则为大端序。

二、如何判断字节序

字节序的判断只需要一段简单的代码即可:

int main()
{
	int x=0x12345678; 
  
    unsigned char *p=(char *)&x;  
    printf("%p %p %p %p\r\n",p,p+1,p+2,p+3);
    printf("%0x %0x %0x %0x\r\n",p[0],p[1],p[2],p[3]);  
}

在ubuntu下的执行结果为:
《c语言主机字节序和网络字节序》

从执行结果可以得到低字节的78存储在低地址0x7ffe4970678c,所以ubuntu的字节序是小端序。

linux下还可以使用shell查看字节序

lscpu | grep -i byte

lscpu表示查看cup的相关信息,grep -i byte表示过滤字节序字段。

三、网络字节序

TCP/IP协议规定:把接收到的第一个字节当作高位字节看待,所以网络字节序是大端序; 我们的电脑和一些常用的处理器芯片大都是小端序的存储方式,在发送数据之前需要进行字节序的转换。

假设我们需要把0x12345678通过udp发送出去,我们在linux上写如下代码:

int buffer = 0x12345678;
ret = sendto(sockfd,&buffer,sizeof(int),0,&dest_addr,sizeof(dest_addr));

通过wireshark抓取得到的数据包为:
《c语言主机字节序和网络字节序》

我们可以使用htonl将主机字节序转换成网络字节序:

int buffer = 0x12345678;
buffer = htonl(buffer);
ret = sendto(sockfd,&buffer,sizeof(int),0,&dest_addr,sizeof(dest_addr));

使用wireshark抓取得到的数据如下:
《c语言主机字节序和网络字节序》

    原文作者:知无止境
    原文地址: https://blog.csdn.net/weixin_39270987/article/details/109719416
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞