C++實現(xiàn)主機字節(jié)序和網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換示例
字節(jié)序問題
現(xiàn)代CPU一次至少能裝載4字節(jié)(32位機),即一個整數(shù),這4個字節(jié)在內(nèi)存中的排列順序?qū)⒂绊懰闹?。這就是字節(jié)序問題。字節(jié)序分為大端字節(jié)序(big endian)和小端字節(jié)序(little endian)。
如上圖,大端字節(jié)序是指數(shù)據(jù)的高位存在內(nèi)存的低地址處,小端字節(jié)序是指數(shù)據(jù)的高位存在內(nèi)存的高地址處。
現(xiàn)代PC大多采用小端字節(jié)序
當(dāng)格式化的數(shù)據(jù)需要在兩臺使用不同字節(jié)序的主機進行傳遞時,接收端會錯誤的處理。解決的方法是:發(fā)送端將發(fā)送的數(shù)據(jù)轉(zhuǎn)換成大端字節(jié)序然后發(fā)送,接收端根據(jù)自己的字節(jié)序決定需不需要處理(小端轉(zhuǎn)換,大端不處理)。
在做網(wǎng)絡(luò)編程的時候,使用提供的庫即可進行轉(zhuǎn)換(linux庫,windows下是一樣的,頭文件有所區(qū)別)
#include <netinet/in.h> unsigned long int _htonl(unsigned long int hostlong); unsigned short int _htons(unsigned short int hostshort); unsigned long int _ntohl(unsigned long int netlong); unsigned short int _ntohs(unsigned short int netshort);
互換數(shù)據(jù)
如果平臺沒有提供這套,那么可以自己實現(xiàn)一下,原理很簡單,就是互換下數(shù)據(jù)
#include <stdint.h> #define BigLittleSwap16(v) ((0xFF00 & (uint16_t)(v)) >> 8 | (0x00FF & (uint16_t)(v)) << 8) #define BigLittleSwap32(v) ((0xFF000000 & (uint32_t)(v)) >> 24 | (0x00FF0000 & (uint32_t)(v)) >> 8 | (0x0000FF00 & (uint32_t)(v)) << 8 | (0x000000FF & (uint32_t)(v)) << 24) #define BigLittleSwap64(v) ((0xFF00000000000000 & (uint64_t)(v)) >> 56 |(0x00FF000000000000 & (uint64_t)(v)) >> 40 |(0x0000FF0000000000 & (uint64_t)(v) )>> 24 |(0x000000FF00000000 & (uint64_t)(v)) >> 8 |(0x00000000FF000000 & (uint64_t)(v)) << 8| (0x0000000000FF0000 & (uint64_t)(v)) << 24 | (0x000000000000FF00 & (uint64_t)(v) )<< 40 | (0x00000000000000FF & (uint64_t)(v) )<< 56 ) int isCPUBigEndian(){ union Data{ short val; char byte; } data; data.val = 0x0102; return (data.byte == 0x01); } unsigned long int _htonl(unsigned long int hostlong); unsigned short int _htons(unsigned short int hostshort); unsigned long int _ntohl(unsigned long int netlong); unsigned short int _ntohs(unsigned short int netshort); unsigned long int _htonl(unsigned long int hostlong){ return isCPUBigEndian() ? hostlong : BigLittleSwap32(hostlong); } unsigned short int _htons(unsigned short int hostshort){ return isCPUBigEndian() ? hostshort : BigLittleSwap16(hostshort); } unsigned long int _ntohl(unsigned long int netlong){ return isCPUBigEndian() ? netlong : BigLittleSwap32(netlong); } unsigned short int _ntohs(unsigned short int netshort){ return isCPUBigEndian() ? netshort : BigLittleSwap16(netshort); }
測試
#include <netinet/in.h> #include <stdio.h> int main(int argc,const char*argv[]){ long int v1 = 0x11223344; short int v2 = 0x1122; printf("the endian of system is:%s\n",isCPUBigEndian()?"Big Endian":"Little Endian"); printf("htonl:%x , %x , %x\n",v1,htonl(v1),_htonl(v1)); printf("htons:%x , %x , %x\n",v2,htons(v2),_htons(v2)); printf("ntohl:%x , %x , %x\n",v1,ntohl(v1),_ntohl(v1)); printf("ntohs:%x , %x , %x\n",v2,htons(v2),_htons(v2)); return 0; }
在linux下的測試結(jié)果如下圖
以上就是C++實現(xiàn)主機字節(jié)序和網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換示例的詳細(xì)內(nèi)容,更多關(guān)于C++主機網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決pip?install?dlib報錯C++11?is?required?to?use?dlib
這篇文章主要介紹了在使用pip?install?dlib安裝dlib的時候報錯C++11?is?required?to?use?dlib的解決方法,需要的的小伙伴可以參考一下,希望對你有所幫助2022-02-02C++字符數(shù)組的輸入輸出和字符串結(jié)束標(biāo)志使用講解
這篇文章主要介紹了C++字符數(shù)組的輸入輸出和符串結(jié)束標(biāo)志使用講解,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09C++實現(xiàn)LeetCode(109.將有序鏈表轉(zhuǎn)為二叉搜索樹)
這篇文章主要介紹了C++實現(xiàn)LeetCode(109.將有序鏈表轉(zhuǎn)為二叉搜索樹),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07淺談C++ Explicit Constructors(顯式構(gòu)造函數(shù))
下面小編就為大家?guī)硪黄獪\談C++ Explicit Constructors(顯式構(gòu)造函數(shù))。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-12-12