通俗易懂说字节序,大小端,网络序和主机序(2)htonl和ntohl 源码实现

  • 1. htonl 内核源码实现
    • 1.1 注意:这里有判断,如果本身内存中存储的就是网络序,那就不转
    • 1.1 __bswap_32()例子
  • 2. ntohl
  • 3. 解释了为什么项目中的都用htonl 问题
  • 4. long long类型(8字节)字节序转换
    • 4.1 方法1: 使用位移
    • 4.2 方法2:使用联合体union
    • 4.3 方法3:使用编译器内置函数
  • 参考

上个博客:
通俗易懂说字节序,大小端,网络序和主机序
https://blog.csdn.net/lqy971966/article/details/93602177

1. htonl 内核源码实现

系统函数htonl在头文件 netinet/in.h中

# if __BYTE_ORDER == __BIG_ENDIAN
/* The host byte order is the same as network byte order,
so these functions are all just identity.
如果系统是 BIG_ENDIAN 那么网络字节序(大端)和运算字节序是一致的 不用处理
*/
# define ntohl(x)    (x)
# define ntohs(x)    (x)
# define htonl(x)    (x)
# define htons(x)    (x)
# else
#  if __BYTE_ORDER == __LITTLE_ENDIAN
/*
如果是 LITTLE_ENDIAN 那么需要进行 __bswap_32() 操作
*/
#   define ntohl(x)    __bswap_32 (x)
#   define ntohs(x)    __bswap_16 (x)
#   define htonl(x)    __bswap_32 (x)
#   define htons(x)    __bswap_16 (x)
#  endif
# endif
#endif

1.1 注意:这里有判断,如果本身内存中存储的就是网络序,那就不转

如:

ip地址存的时候是网络序(大端),进程间通信转序处理
这里跳过了,都是大端,跳过


__bswap_32() 在 gcc 中实现,位于bits/byteswap.h(不要直接引用此文件;使用 byteswap.h 中的 bswap32 代替):

/* Swap bytes in 32 bit value.  */
#define __bswap_constant_32(x) \((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >>  8) |         \(((x) & 0x0000ff00u) <<  8) | (((x) & 0x000000ffu) << 24))

1.1 __bswap_32()例子

 例如: 0x1234 二进制: 00000001 00000010 00000011 00000100((x) & 0xff000000u) 结果是: 0x1000 >> 24 就是 0x0001((x) & 0x00ff0000u) 结果是: 0x0200 >> 8  就是 0x0020((x) & 0x0000ff00u) 结果是: 0x0030 << 8  就是 0x0300((x) & 0x000000ffu) 结果是: 0x0004<< 24 就是 0x4000然后进行 | 或操作 就是 0x4321

2. ntohl

同理 htonl 一样处理

3. 解释了为什么项目中的都用htonl 问题

  1. 项目中都使用 htonl ,系统发消息使用 htonl ,另外接收的时候也用 htonl。
    因为 htonl 和 ntohl 仅仅名字不同,实现是一样的,
    如上面所示:
    都是 __bswap_32
    define htonl(x) __bswap_32 (x)
    define ntohl(x) __bswap_32 (x)

4. long long类型(8字节)字节序转换

上边的几个函数有对32位和16位的数值转换,但是如果是64位的就没有现成的API可以调用了

4.1 方法1: 使用位移

//主机序转网络序
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;}
}//网络序转主机序
unsigned long long ntohll(unsigned long long val)
{if (__BYTE_ORDER == __LITTLE_ENDIAN) {return (((unsigned long long )ntohl((int)((val << 32) >> 32))) << 32) | (unsigned int)ntohl((int)(val >> 32));}else if (__BYTE_ORDER == __BIG_ENDIAN) {return val;}
}

4.2 方法2:使用联合体union

边使用联合体的特性:联合体中所有成员引用的是内存中相同的位置,其长度为最长成员的长度。

typedef struct {  unsigned int u32_h;  unsigned int u32_l;
}Int64_t;  typedef union {  unsigned long long u64;  Int64_t st64;
}Convert64_t;//主机序转网络序
unsigned long long htonll(unsigned long long val)
{  if (__BYTE_ORDER == __LITTLE_ENDIAN){Convert64_t box_in, box_out;  box_in.u64 = val;  box_out.st64.u32_h = htonl(box_in.st64.u32_l);  box_out.st64.u32_l = htonl(box_in.st64.u32_h);  return box_out.u64;}else if (__BYTE_ORDER == __BIG_ENDIAN)  {  return val;}
}//网络序转主机序
unsigned long long ntohll(unsigned long long val)
{if (__BYTE_ORDER == __LITTLE_ENDIAN){Convert64_t box_in, box_out;  box_in.u64 = val;  box_out.st64.u32_h = ntohl(box_in.st64.u32_l);  box_out.st64.u32_l = ntohl(box_in.st64.u32_h);  return box_out.u64;}else if(__BYTE_ORDER == __BIG_ENDIAN){return val;}
}

4.3 方法3:使用编译器内置函数

#ifdef WIN32
#define ntohll(x) _byteswap_uint64 (x)
#define htonll(x) _byteswap_uint64 (x)
#else
#if __BYTE_ORDER == __BIG_ENDIAN
#define ntohll(x) (x)
#define htonll(x) (x)
#else
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define ntohll(x) __bswap_64 (x)
#define htonll(x) __bswap_64 (x)
#endif
#endif
#endif

参考

https://www.cnblogs.com/pied/p/5371231.html

通俗易懂说字节序,大小端,网络序和主机序(2)htonl和ntohl 源码实现相关推荐

  1. java毕业设计——基于Java+Java ME的无线网络移动端的俄罗斯方块游戏设计与实现(毕业论文+程序源码)——俄罗斯方块游戏

    基于Java+Java ME的无线网络移动端的俄罗斯方块游戏设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于Java+Java ME的无线网络移动端的俄罗斯方块游戏设计与实现,文章末尾附有 ...

  2. Android毕业设计——基于Android+Tomcat的网络视频探索系统设计与实现(毕业论文+程序源码)——网络视频探索系统

    基于Android+Tomcat的网络视频探索系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于Android+Tomcat的网络视频探索系统设计与实现,文章末尾附有本毕业设计的论文和源 ...

  3. APICloud AVM多端开发 |《生鲜电商app开发》项目源码深度解析

    此项目为生鲜电商app开发类应用,主要功能包括商品列表.商品详情展示.购物车.登录注册.个人中心等. 项目源码在 https://github.com/apicloudcom/avm-simple 仓 ...

  4. java毕业设计——基于JSP+sqlserver的网络在线考试系统设计与实现(毕业论文+程序源码)——在线考试系统

    基于JSP+sqlserver的网络在线考试系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于JSP+sqlserver的网络在线考试系统设计与实现,文章末尾附有本毕业设计的论文和源码下 ...

  5. asp毕业设计—— 基于asp+access的网络招聘管理系统设计与实现(毕业论文+程序源码)——网络招聘管理系统

    基于asp+access的网络招聘管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于asp+access的网络招聘管理系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦.需 ...

  6. C#毕业设计——基于C#+asp.net+sqlserver的网络在线考试系统设计与实现(毕业论文+程序源码)——网络在线考试系统

    基于C#+asp.net+sqlserver的网络在线考试系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C#+asp.net+sqlserver的网络在线考试系统设计与实现,文章末尾 ...

  7. java计算机毕业设计网络城市交通应急管理系统MyBatis+系统+LW文档+源码+调试部署

    java计算机毕业设计网络城市交通应急管理系统MyBatis+系统+LW文档+源码+调试部署 java计算机毕业设计网络城市交通应急管理系统MyBatis+系统+LW文档+源码+调试部署 本源码技术栈 ...

  8. PHP网络开发设计建站工作室接单网站源码

    介绍: PHP网络开发设计建站工作室接单网站源码,内附简单安装说明 网盘下载地址: https://zijiewangpan.com/9C2RduZDP4h 图片:

  9. 计算机毕业设计ssm基于网络的景区旅游服务管理系统q57ng系统+程序+源码+lw+远程部署

    计算机毕业设计ssm基于网络的景区旅游服务管理系统q57ng系统+程序+源码+lw+远程部署 计算机毕业设计ssm基于网络的景区旅游服务管理系统q57ng系统+程序+源码+lw+远程部署 本源码技术栈 ...

最新文章

  1. basequickadapter详解_在kotlin中如何使用BaseQuickAdapter适配器
  2. 对于生活服务小公司网站的看法
  3. Android RecyclerView
  4. QT利用QCustomplot绘制折线图海底声速梯度图,解决一条曲线中一个X值对应两个Y值
  5. SpringBoot、mysql配置PageHelper插件
  6. 在 .NET Core 3.0 中实现 JIT 编译的 JSON 序列化,及一些心得与随想
  7. 送福利:ROKID 语音开发板免费送,开启你的物联网之旅
  8. 狗窝里的小日子- 6 ...
  9. 通用职责分配软件原则之2-创造者原则
  10. 物体抓取位姿估計算法綜述_3D视觉技术在机器人抓取作业中的应用
  11. “单口相声”回归!罗永浩要开发布会了:黑科技!不售票!
  12. persistence java_Java数据持久层 - Persistence Manager Factory
  13. 购买课程赠老男孩出版的签名新书啦!
  14. 【AAA】AAA协议介绍
  15. Hadoop源码分析28 JobTracker 处理JobClient请求
  16. win 10 使用技巧总结
  17. 高通X12平台XO信号干扰灵敏度的解决方案
  18. linux系统安装pidgin,linux下QQ的安装(pidgin的安装)
  19. 资源(电影、英剧、美剧、日剧、动漫、纪录片)网站
  20. Springboot启动报错-类文件具有错误的版本 61.0, 应为 52.0

热门文章

  1. 初学STM32之定时器中断
  2. STM32-定时器中断实验
  3. 在线分析仪器(六)防护等级与隔爆等级
  4. GIS空间分析实验教程期末重点1718
  5. 灰狼算法GWO优化径向基网络做回归预测,多输入单输出模型。GWO-RBF
  6. CSP考试复习:第二单元 基础算法 2.5 常见的递推关系!
  7. 基于计算机视觉的智能交通监控系统
  8. 无MMU实现非法内存访问安全的一种方法
  9. 用计算机绘制颗粒级配曲线,巧用excel绘制颗粒级配曲线与自动计算粒组特征参数...
  10. 一键开启/禁用以太网