网络字节序转换的操作函数有这几个 ntohs() 、htons() 、 ntohl() 、htonl() ,不同平台下这几个函数依赖的头文件各有千秋,而且还没有 64位的转换接口。写跨平台代码的时候,为了省掉这些差异,干脆自己来实现一套,这里做个笔记。
参看 Linux 内核的源代码,是类似于这样实现的:
static union
{
x_char_t xct_order[4];
x_uint32_t xut_order;
} xhost_order = { { 'L', '?', '?', 'B' } };
#define X_IS_LITTLE_ENDIAN ('L' == (x_char_t)xhost_order.xut_order)
#define X_IS_BIG_ENDIAN ('B' == (x_char_t)xhost_order.xut_order)
代码如下所示:
typedef char x_char_t;
typedef unsigned short x_uint16_t;
typedef unsigned int x_uint32_t;
typedef unsigned long long x_uint64_t;
/**
* @brief 用于进行判断主机字节序的联合体。
* @note
* 小端:低地址存放低字节,高地址存放高字节;
* 大端:高地址存放低字节,低地址存放高字节;
* 网络字节序是大端。
*/
static union
{
x_char_t xct_order[4];
x_uint32_t xut_order;
} xhost_order = { { 'L', '?', '?', 'B' } };
#define X_IS_LITTLE_ENDIAN ('L' == (x_char_t)xhost_order.xut_order)
#define X_IS_BIG_ENDIAN ('B' == (x_char_t)xhost_order.xut_order)
/**********************************************************/
/**
* @brief 字节序转换:16 位整数从 网络字节序 转成 主机字节序。
*/
x_uint16_t vx_ntohs(x_uint16_t xut_short)
{
if (X_IS_LITTLE_ENDIAN)
return ((xut_short << 8) | (xut_short >> 8));
return xut_short;
}
/**********************************************************/
/**
* @brief 字节序转换:16 位整数从 主机字节序 转成 网络字节序。
*/
x_uint16_t vx_htons(x_uint16_t xut_short)
{
if (X_IS_LITTLE_ENDIAN)
return ((xut_short << 8) | (xut_short >> 8));
return xut_short;
}
/**********************************************************/
/**
* @brief 字节序转换:32 位整数从 网络字节序 转成 主机字节序。
*/
x_uint32_t vx_ntohl(x_uint32_t xut_long)
{
if (X_IS_LITTLE_ENDIAN)
return (((xut_long ) << 24) |
((xut_long & 0x0000FF00) << 8) |
((xut_long & 0x00FF0000) >> 8) |
((xut_long ) >> 24));
return xut_long;
}
/**********************************************************/
/**
* @brief 字节序转换:32 位整数从 主机字节序 转成 网络字节序。
*/
x_uint32_t vx_htonl(x_uint32_t xut_long)
{
if (X_IS_LITTLE_ENDIAN)
return (((xut_long ) << 24) |
((xut_long & 0x0000FF00) << 8) |
((xut_long & 0x00FF0000) >> 8) |
((xut_long ) >> 24));
return xut_long;
}
/**********************************************************/
/**
* @brief 字节序转换:64 位整数从 网络字节序 转成 主机字节序。
*/
x_uint64_t vx_ntohll(x_uint64_t xult_llong)
{
if (X_IS_LITTLE_ENDIAN)
return (((xult_llong ) << 56) |
((xult_llong & 0x000000000000FF00) << 40) |
((xult_llong & 0x0000000000FF0000) << 24) |
((xult_llong & 0x00000000FF000000) << 8) |
((xult_llong & 0x000000FF00000000) >> 8) |
((xult_llong & 0x0000FF0000000000) >> 24) |
((xult_llong & 0x00FF000000000000) >> 40) |
((xult_llong ) >> 56));
return xult_llong;
}
原文:https://www.cnblogs.com/Gaaagaa/p/12130831.html