zoukankan      html  css  js  c++  java
  • 自己实现的网络字节序转换函数

    网络字节序转换的操作函数有这几个 ntohs()htons()ntohl()htonl() ,不同平台下这几个函数依赖的头文件各有千秋,而且还没有 64位的转换接口。写跨平台代码的时候,为了省掉这些差异,干脆自己来实现一套,这里做个笔记。

    1. 知识要点

    • 大端模式(Big-endian):是指数据的高字节,保存在内存的低地址中,而数据的低字节,保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放。
    • 小端模式(Little-endian):是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内在的低地址中,这种存储模式将地址的高低和数据位 权有效结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
    • 主机字节序:是指 整数(如16位,32位,64位这些类型的整数) 在内存中保存的顺序,不同的 CPU 可能使用不同的字节序类型,现下绝大多数使用小端模式。
    • 网络字节序:网络字节序是使用大端的模式。

    2. 判断主机字节序

    参看 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)
    

    3. 自己实现的网络字节序转换函数

    代码如下所示:

    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;
    }
    
  • 相关阅读:
    tftp服务、串口工具minicom
    意外的“黄金点”
    软件工程实践总结
    关于 K米 —— 的案例分析
    关于git的学习
    第二次作业_需求分析与原型设计
    安装appium
    淘宝
    Selenium API基础 8种定位
    selenium
  • 原文地址:https://www.cnblogs.com/VxGaaagaa/p/11519983.html
Copyright © 2011-2022 走看看