用计算器实现主机字节序与网络字节序之间转换

         一直以来我们在字节序做转换的时候,大多是查的相关的函数,当然这些函数都能解决你的问题,但对原理可能理解大概有点模糊,面试时深入点可能就会回答不完整。写这遍文章原因是在看代码调试过程中遇到网络字节序要转主机字节序,通常的方法写测试代码,现在简单介绍另外一种测试方法《计算器》--程序员 版,顺带了解转换原理。

先了解操作系统常用的存储方法:

小端字节序:低字节存于内存低地址;高字节存于内存高地址;(符合正常思维逻辑)
大端字节序:高字节存于内存低地址;低字节存于内存高地址;(有点B格,用到最多是网络数据传输时)

下面我们以网络端口为例讲下转换过程: 主机 6000(小端) --> 网络 28695‬(大端)

        DEC: 6000 ,  HEX :1770,      BIN:0001 0111 0111 000

存储原理: 整数存储按最小存储单元为 四字节,分高位二字节,低位二字节【二字节分高低各8位】

简单版: 低位二字节在高低字节内转换 (高低字节:高8bit,低8bit) ,验证函数:htons()

       1、 一字节:以 整数1为例 =====> (一般存低位二字节的低8位【低4位上】)

             整数1 :00000000 00000001 , 按简单版转换方法 ==> 00000001 00000000 (256)

       2、一字节:以 整数32为例 =====> (一般存低位二字节的低8位【高4位上】)

             整数32:00000000 00100000,按简单版转换方法 ==> 00100000 00000000 (8192)

       3、二字节:(一般存低位二字节上【 分高8位,低8位】 )

            按实例整数6000分析:将高八位(8bit)与低八位换位(8bit)

            0001 0111 0111 000   按二字节描述转换 ==>  0111000 00010111 (7017) ===>‭28695‬

           额外加一个整数,留意转换结果:

            整数512 : 00000010 00000000 ,同理按上面方法 ==> 00000000 00000010 (2)

 

加强版:占用三个字节或四个字节,转换过程有点变化,占用高二字节,低二字节

        4、三字节:(一般存高位的低二字节【低4位上】和低位二字节上),验证函数:htonl()

             整数 65539:(实际存储,往下) ===> 50331904

                     高位: 00000000 00000000 00000000 00000001

                     低位: 00000000 00000000 00000000 00000011

            过程1:先高位与低们转换位置 (往下)

                     高位: 00000000 00000000 00000000 00000011

                     低位: 00000000 00000000 00000000 00000001

            过程2:再在高位中进行二字节高低字节转换(低位同方法)

                    高位: 00000000 00000011 00000000 00000000

                   低位: 00000000 00000001 00000000 00000000

针对加强版附上图片分析,主要是有两个过程更有助于理解:

        

转换过程1:先高低二字节转换,未完

           

转换过程2 :再分别在二字节中进行,高低位转换,OK,最终完成。当然四字节的数跟三字节一样,暂时不分析。

          

超强版:8字节64位,这种情况在网络传输数据中也遇到过,当然系统好像没有针对性的函数,下面贴出网友贡献出来的函数。

       优点:做了适配系统。(网上一大把,推荐这种方式)

unsigned long long ntohll(unsigned long long val)
{
    if (__BYTE_ORDER == __LITTLE_ENDIAN)
    {
        return (((unsigned long long )htonl((int)((val << 32) >> 32))) << 32) | (unsigned int)htonl((int)(val >> 32));
    }
    else if (__BYTE_ORDER == __BIG_ENDIAN)
    {
        return val;
    }
}
 
unsigned long long htonll(unsigned long long val)
{
    if (__BYTE_ORDER == __LITTLE_ENDIAN)
    {
        return (((unsigned long long )htonl((int)((val << 32) >> 32))) << 32) | (unsigned int)htonl((int)(val >> 32));
    }
    else if (__BYTE_ORDER == __BIG_ENDIAN)
    {
        return val;
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值