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下的执行结果为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h249YuCY-1605505603244)(F9E0E3F35D694C0F9A4767AC1F62F26F)]

从执行结果可以得到低字节的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抓取得到的数据包为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O1xC6YO5-1605505603246)(3DB291F709EA465C8F22BBF4A87A76BB)]

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

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

使用wireshark抓取得到的数据如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GHXOeh1a-1605505603247)(D765F3E188B944F08A3B5C901E8FF633)]

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值