因为需要直接处理一个网络字节序的 32 位 int,所以,考虑用自己写的还是系统函数效率更高。然后又了下面的了解。

首先是系统函数 htonl ,我在 kernel 源码 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.  */
# define ntohl(x)    (x)
# define ntohs(x)    (x)
# define htonl(x)    (x)
# define htons(x)    (x)
# else
#  if __BYTE_ORDER == __LITTLE_ENDIAN
#   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

可以看到,如果系统是 BIG_ENDIAN 那么网络字节序和运算字节序是一致的,如果是 LITTLE_ENDIAN 那么需要进行 __bswap_32() 操作。__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))

如果 CPU 直接支持 bswap32 操作,那这里该用汇编来写? 以提高效率。

网络上是一个个字节传的,而 int 是 32 位,所以,我又定义了这个 union:

union
{unsigned int ber32;char mem[4];
} currentData;

这样,就直接把各个 byte 给直接取出来了。

所以,按这个思路,完整的过程就是:

#if BYTE_ORDER == BIG_ENDIAN#warning "BIG_ENDIAN SYSTEM!"currentData.ber32 = sampleValue;
#elif BYTE_ORDER == LITTLE_ENDIAN#warning "LITTLE_ENDIAN SYSTEM!"currentData.ber32 = bswap_32(sampleValue);
#else#error "No BYTE_ORDER is defined!"
#endifsendBuf[bufPos++] = currentData.mem[0];sendBuf[bufPos++] = currentData.mem[1];sendBuf[bufPos++] = currentData.mem[2];sendBuf[bufPos++] = currentData.mem[3];

从网络字节序取出数值时候,赋值和 bswap 过程反一下就好。

从网络字节序直接恢复出数值的另一个思路是,既然网络字节序是确定的,那么可以用移位累加的方法直接求出这个 int,如下:

sampleValue = 0;

sampleValue += (buff[posOfSamples + 0] << (8 * 3)) );
sampleValue += (buff[posOfSamples + 1] << (8 * 2)) );
sampleValue += (buff[posOfSamples + 2] << (8 * 1)) );
sampleValue += (buff[posOfSamples + 3] << (8 * 0)) );

虽然后面一个比 bswap 多几个 cpu 时间,但是,明显可读性要高一些。

关于 htonl 和 ntohl 的实现相关推荐

  1. 【VS开发】IP地址格式转换(htonl、ntohl;inet_addr、inet_ntoa)

    1.htonl ()和ntohl( ) u_long PASCAL FAR ntohl (u_long netlong); u_short PASCAL FAR ntohs (u_short nets ...

  2. 【网络】IP地址格式转换(htonl、ntohl;inet_addr、inet_ntoa)

    1.htonl ()和ntohl( ) u_long PASCAL FAR ntohl (u_long netlong); u_short PASCAL FAR ntohs (u_short nets ...

  3. Socket中常见的几个转换函数(htonl,htons,ntohl,ntohs,inet_addr,inet_ntoa)

    Socket中常见的几个转换函数(htonl,htons,ntohl,ntohs,inet_addr,inet_ntoa) htonl() htons() ntohl() ntohs()及inet_n ...

  4. htonl,htons,ntohl,ntohs的详解

    大小端模式 对于多字节的数值在系统中如何存储取决于各CPU的实现,而高字节部分是存在低地址还是高地址就有不一样的结果了,因此才有大小端两种模式的存在,而命名则是根据起始地址存放的是数值字节的低处还是高 ...

  5. htons(), htonl(), ntohs(), ntohl()

    在网络编程中,往往会遇到字节的网络顺序和主机顺序的问题. 我们先来了解下字节的网络顺序和主机顺序: 网络字节序与主机字节序 主机字节序:就是我们平常说的大端和小端模式,不同的CPU有不同的字节序类型, ...

  6. 模拟htonl、ntohl、htons、ntohs函数实现

    模拟htonl.ntohl.htons.ntohs函数实现 2010-04-14 17:25:06|  分类: 网络编程 |  标签: |字号大中小 订阅 From: http://wxxweb.bl ...

  7. 主机字节序与网络字节序的转换函数:htonl、ntohl、htons、ntohs

    Part 1: htons函数具体解释      在Linux和Windows网络编程时需要用到htons和htonl函数,用来将主机字节顺序转换为网络字节顺序. 在Intel机器下,执行以下程序 i ...

  8. htonl函数 c语言,c – 理解htonl()和ntohl()

    我试图使用unix套接字测试发送一些udp数据包到localhost. 我的理解是,当设置ip地址和端口以便发送数据包时,我会将我的sockaddr_inwith填充为转换为网络字节顺序的值. 我在O ...

  9. 记录一次htonl和ntohl的使用方法和差别

    实例: 在研究这两个函数时,总是遇到htonl和ntohl输出的值是一样的情况,明明一个是主机序转网络序,一个是网络序转主机序,为什么值会输出一样呢?请看代码: uint32_t ulTemp = 1 ...

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

    通俗易懂说字节序,大小端,网络序和主机序(2)htonl和ntohl 源码实现 1. htonl 内核源码实现 1.1 注意:这里有判断,如果本身内存中存储的就是网络序,那就不转 1.1 __bswa ...

最新文章

  1. pads最新版本是多少_电路EDA软件究竟有多少?
  2. Fiddler抓取手机APP数据包
  3. Xcode生成的可执行文件在哪里
  4. android uinput 按键_android 使用uinput模拟输入设备的方法
  5. opc服务器状态红叉,西门子S7-300与上位机通过OPC服务器的通讯设置分解.pdf
  6. shell mysql eof_shell EOF
  7. label居中_表格固定列宽时如何居中?
  8. 《构建之法》第8,9,10章
  9. ROS queue_size和buff_size设置
  10. java声明代码是什么_java安全编码指南之:声明和初始化说明
  11. 企业私有云之rabbitmq高可用
  12. 简单使用apipost和jmeter 测试接口
  13. iOS申请真机调试证书 图文详解
  14. 【学习笔记】python实现图像的手绘效果
  15. w ndows默认截图工具,windows截图工具快捷键
  16. 淘宝卖家过劳死VS跳楼死
  17. 07、Flutter FFI 数组
  18. 涂抹果酱【状压DP】
  19. 高仿QQ源码 界面(3)
  20. 沃达丰高管:澳大利亚将于2020年迎来5G

热门文章

  1. 设计模式一:设计模式遵循的原则
  2. 格式化大容量硬盘为fat32
  3. 百度网盘推荐部分优秀的分享达人
  4. SQL Server使用ROW_NUMBER函数进行分页
  5. 51CTO第2本书样章曝光:DHCP服务器规划与应用案例
  6. python遍历字典方法总结
  7. 【HTTP协议】HTTP状态码列表大全
  8. 【全文搜索引擎】Elasticsearch相关介绍与linux系统安装
  9. ssl mybatis实现数据库字段的加解密
  10. Common Attention Points