字节排序函数

       考虑一个16位整数,它由两个字节组成。内存中存储这两个字节有两种方法:一种是将低序字节存储在起始地址,这称为小端(little-endian)字节序;另一种是将高序字节存储在起始地址,这称为大端(big-endian)字节序。图1展示了这两种格式。

       图1  16位整数的小端字节序和大端字节序

       在该图中,我们在顶部标明内存地址增长的方向为从右到左,在底部标明内存地址增长的方向为从左到右。我们还标明最高有效位(most significant bit, MSB)是这个16位值最左边一位,最低有效位(leastsignificant bit, LSB)是这个16位值最右边一位。

       术语“小端”和“大端”表示多个字节值的哪一端(小端或大端)存储在该值的起始地址。

       遗憾的是,这两种字节序之间没有标准可循,两种格式都有系统使用。我们把某个给定系统所用的字节序称为主机字节序(host byte order)。图2所示程序输出主机字节序。 

 

   #include <stdio.h>
	
  int main(void)
  {
        union {
            short   s;
            char    c[sizeof(short)];
        } un;
        un.s = 0x0102;
       if (sizeof(short) == 2) {
            if (un.c[0] == 1 && un.c[1] == 2) {
                printf("big-endian\n");
            } else if (un.c[0] == 2 && un.c[1] == 1) {
                printf("little-endian\n");
            } else {
                printf("unknown\n");
            }
        } else {
            printf("sizeof(short) = %d\n", sizeof(short));
        }
        return 0;
    }

         图2确定主机字节序的程序

       我们在短整数变量中存放两字节的值0x0102,然后查看它的两个连续字节c[0](对应图1中的地址A)和c[1](对应图1中的地址A+1),以此确定字节序。

       我们已讨论了16位整数的字节序,显然,同样的讨论也适用于32位整数。

       既然网络协议必须指定一个网络字节序(network byte order),作为网络编程人员的我们必须清楚不同字节序之间的差异。举例来说,在每个TCP报文段中都有16位的端口号和32位的IPv4地址。发送协议栈和接收协议栈必须就这些多字节字段各个字节的传送顺序达成一致。网际协议使用大端字节序来传送这些多字节整数。

       从理论上说,具体实现可以按主机字节序存储套接字地址结构中的各个字段,等到需要在这些字段和协议首部相应字段之间转移时,再在主机字节序和网络字节序之间进行互换,让我们免于操心转换细节。然后由于历史的原因和POSIX规范的规定,套接字地址结构中的某些字段必须按照网络字节序进行维护。因此我们要关注如何在主机字节序和网络字节序之间相互转换。这两种字节序之间的转换使用以下4个函数:

       #include<netinet/in.h>

       uint16_thtons(uint16_t host16bitvalue);

       uint32_thtonl(uint32_t host32bitvalue);

                                                       均返回:网络字节序的值

       uint16_tntohs(uint16_t net16bitvalue);

       uint32_tntohl(uint32_t net32bitvalue);

                                                       均返回:主机字节序的值

       在这些函数的名字中,h代表hostn代表networks代表shortl代表long

       当使用这些函数时,我们并不关心主机字节序和网络字节序的真实值(或为大端,或为小端)。我们所要做的只是调用适当的函数在主机和网络字节序之间转换某个给定值。在那些与网际协议所用字节序(大端)相同的系统中,这四个函数通常被定义为空宏。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值