The principle network byte order conversion function

Network byte order conversion function has several operating ntohs () , the htons () , ntohl () , htonl () , the function of these different platforms dependent header files is different, but also not a 64-bit conversion interface . When writing cross-platform code, in order to save these differences, simply set themselves to achieve, make a note here.

1. Knowledge points

  • Big endian (Big-endian) : refers to the high byte of data, stored in the lower memory address, the least significant byte of data stored in the high address memory, such a bit pattern similar to the data storage as strings order: address increase from small to large, and the data from the high to the low discharge.
  • Little endian (Little-endian) : refers to the high byte of data stored in the upper memory address, the least significant byte of data stored in the inner lower address, this data storage mode and the low address bits right effectively combine high portion of high weight and low weight the low address section, and methods consistent with our logic.
  • Host byte sequence : refers to an integer (e.g., 16-bit, 32-bit, 64-bit integer of these types) stored sequentially in memory, the CPU may use different byte order different types, using little-endian mode majority holds many lessons .
  • Network byte order : using the network byte order is big endian mode.

2. Analyzing master endianness

Referring source Linux kernel, similar to this is achieved:

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)

3. own implementation of network byte order conversion function

Code as follows:

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;
}

Guess you like

Origin www.cnblogs.com/Gaaagaa/p/12130831.html