<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      網絡字節序與主機字節序的相互轉換

      1.網絡字節序與主機字節序

      在Linux網絡編程中,經常碰到網絡字節序與主機字節序的相互轉換。說到網絡字節序與主機字節序需要清晰了解以下幾個概念。

      字節序,顧名思義,指字節在內存中存儲的順序。比如一個int32_t類型的數值占用4個字節,這4個字節在內存中的排列順序就是字節序。字節序有兩種:
      (1)小端字節序(Little endinan),數值低位存儲在內存的低地址,高位存儲在內存的高地址;
      (2)大端字節序(Big endian),數值高位存儲在內存的低地址,低位存儲在內存的高地址。

      下面以32位位寬數值0x12345678為例,小端字節序與大端字節序具體的存儲區別如下所示:

       

      主機字節序,即CPU存儲數據時采用的字節順序。不同的CPU設計時采用的字節序是不同的,談到字節序的問題,必然牽涉到兩大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86與x86_64(該指令集由AMD率先設計推出)系列CPU。PowerPC系列采用big endian方式存儲數據,而x86與x86_64系列則采用little endian方式存儲數據。平常大多數PC與服務器如果使用的是Intel與AMD CPU,一般都是little endian。

      如何具體判斷本機的主機字節序呢?參考如下代碼:

      //@ret:返回0小端字節序,返回1大端字節序
      int dGetHostByteOrder()
      {
          uint32_t a = 0x12345678;  
          uint8_t *p = (uint8_t *)(&a);  
          if(*p==0x78)
          {
              return 0
          }
          else
          {
              return 1;
          }
      }

      網絡字節序,是TCP/IP中規定好的一種數據表示格式,它與具體的CPU類型、操作系統等無關,從而可以保證數據在不同主機之間傳輸時能夠被正確解釋。網絡字節順序采用big endian排序方式。

       

      2.網絡字節序與主機字節序的相互轉換

      2.1常用系統調用

      Linux socket網絡編程中,經常會使用下面四個C標準庫函數進行字節序間的轉換。

      #include <arpa/inet.h>
      
      uint32_t htonl(uint32_t hostlong);        //把uint32_t類型從主機序轉換到網絡序
      uint16_t htons(uint16_t hostshort);        //把uint16_t類型從主機序轉換到網絡序
      uint32_t ntohl(uint32_t netlong);        //把uint32_t類型從網絡序轉換到主機序
      uint16_t ntohs(uint16_t netshort);        //把uint16_t類型從網絡序轉換到主機序

      2.2 64位數值的轉換

      現在如果需要對64位類型數據進行主機字節序與網絡字節序的轉換,沒有現成系統API可用,可以通過下面兩種方法進行轉換:

      ###2.2.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;  
          }
       }

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

      2.2.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

       

      posted on 2022-10-07 19:27  小程abc  閱讀(195)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 东京热一精品无码av| 日本免费人成视频在线观看| 国产精品成人久久电影| 性夜黄a爽影免费看| 一本色道久久东京热| 免费观看激色视频网站| 日本一区二区三区视频版| www插插插无码免费视频网站| 国产情侣激情在线对白| 亚洲av成人一区二区三区| 国产清纯在线一区二区| 日韩一区精品视频一区二区| 日本边添边摸边做边爱喷水| 宅男噜噜噜66在线观看| 亚洲人成网站在线观看播放不卡| 精品人妻少妇一区二区三区在线| 狠狠色婷婷久久综合频道日韩 | 亚洲 小说区 图片区 都市| 国产粉嫩学生高清专区麻豆| 亚洲人成18在线看久| 日韩中文字幕高清有码| 北岛玲中文字幕人妻系列| 亚洲偷自拍国综合| 国产 精品 自在 线免费| 亚洲一区二区三级av| 69人妻精品中文字幕| 欧美激情在线播放| 日韩激情无码av一区二区| 秋霞在线观看片无码免费不卡| 99久久精品国产一区二区蜜芽| 亚欧美闷骚院| 日本福利一区二区精品| 国产欧美综合在线观看第十页| 久久久av男人的天堂| 日产精品99久久久久久| 亚洲欧美自偷自拍视频图片| 久久综合综合久久高清免费| 丰满无码人妻热妇无码区| 福贡县| 国产寡妇偷人在线观看| 无码激情亚洲一区|