通俗易懂说字节序,大小端,网络序和主机序(2)htonl和ntohl 源码实现
通俗易懂说字节序,大小端,网络序和主机序(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 问题
- 项目中都使用 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 源码实现相关推荐
- java毕业设计——基于Java+Java ME的无线网络移动端的俄罗斯方块游戏设计与实现(毕业论文+程序源码)——俄罗斯方块游戏
基于Java+Java ME的无线网络移动端的俄罗斯方块游戏设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于Java+Java ME的无线网络移动端的俄罗斯方块游戏设计与实现,文章末尾附有 ...
- Android毕业设计——基于Android+Tomcat的网络视频探索系统设计与实现(毕业论文+程序源码)——网络视频探索系统
基于Android+Tomcat的网络视频探索系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于Android+Tomcat的网络视频探索系统设计与实现,文章末尾附有本毕业设计的论文和源 ...
- APICloud AVM多端开发 |《生鲜电商app开发》项目源码深度解析
此项目为生鲜电商app开发类应用,主要功能包括商品列表.商品详情展示.购物车.登录注册.个人中心等. 项目源码在 https://github.com/apicloudcom/avm-simple 仓 ...
- java毕业设计——基于JSP+sqlserver的网络在线考试系统设计与实现(毕业论文+程序源码)——在线考试系统
基于JSP+sqlserver的网络在线考试系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于JSP+sqlserver的网络在线考试系统设计与实现,文章末尾附有本毕业设计的论文和源码下 ...
- asp毕业设计—— 基于asp+access的网络招聘管理系统设计与实现(毕业论文+程序源码)——网络招聘管理系统
基于asp+access的网络招聘管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于asp+access的网络招聘管理系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦.需 ...
- C#毕业设计——基于C#+asp.net+sqlserver的网络在线考试系统设计与实现(毕业论文+程序源码)——网络在线考试系统
基于C#+asp.net+sqlserver的网络在线考试系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C#+asp.net+sqlserver的网络在线考试系统设计与实现,文章末尾 ...
- java计算机毕业设计网络城市交通应急管理系统MyBatis+系统+LW文档+源码+调试部署
java计算机毕业设计网络城市交通应急管理系统MyBatis+系统+LW文档+源码+调试部署 java计算机毕业设计网络城市交通应急管理系统MyBatis+系统+LW文档+源码+调试部署 本源码技术栈 ...
- PHP网络开发设计建站工作室接单网站源码
介绍: PHP网络开发设计建站工作室接单网站源码,内附简单安装说明 网盘下载地址: https://zijiewangpan.com/9C2RduZDP4h 图片:
- 计算机毕业设计ssm基于网络的景区旅游服务管理系统q57ng系统+程序+源码+lw+远程部署
计算机毕业设计ssm基于网络的景区旅游服务管理系统q57ng系统+程序+源码+lw+远程部署 计算机毕业设计ssm基于网络的景区旅游服务管理系统q57ng系统+程序+源码+lw+远程部署 本源码技术栈 ...
最新文章
- basequickadapter详解_在kotlin中如何使用BaseQuickAdapter适配器
- 对于生活服务小公司网站的看法
- Android RecyclerView
- QT利用QCustomplot绘制折线图海底声速梯度图,解决一条曲线中一个X值对应两个Y值
- SpringBoot、mysql配置PageHelper插件
- 在 .NET Core 3.0 中实现 JIT 编译的 JSON 序列化,及一些心得与随想
- 送福利:ROKID 语音开发板免费送,开启你的物联网之旅
- 狗窝里的小日子- 6 ...
- 通用职责分配软件原则之2-创造者原则
- 物体抓取位姿估計算法綜述_3D视觉技术在机器人抓取作业中的应用
- “单口相声”回归!罗永浩要开发布会了:黑科技!不售票!
- persistence java_Java数据持久层 - Persistence Manager Factory
- 购买课程赠老男孩出版的签名新书啦!
- 【AAA】AAA协议介绍
- Hadoop源码分析28 JobTracker 处理JobClient请求
- win 10 使用技巧总结
- 高通X12平台XO信号干扰灵敏度的解决方案
- linux系统安装pidgin,linux下QQ的安装(pidgin的安装)
- 资源(电影、英剧、美剧、日剧、动漫、纪录片)网站
- Springboot启动报错-类文件具有错误的版本 61.0, 应为 52.0