C++實(shí)現(xiàn)主機(jī)字節(jié)序和網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換示例
字節(jié)序問(wèn)題
現(xiàn)代CPU一次至少能裝載4字節(jié)(32位機(jī)),即一個(gè)整數(shù),這4個(gè)字節(jié)在內(nèi)存中的排列順序?qū)⒂绊懰闹?。這就是字節(jié)序問(wèn)題。字節(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ù)需要在兩臺(tái)使用不同字節(jié)序的主機(jī)進(jìn)行傳遞時(shí),接收端會(huì)錯(cuò)誤的處理。解決的方法是:發(fā)送端將發(fā)送的數(shù)據(jù)轉(zhuǎn)換成大端字節(jié)序然后發(fā)送,接收端根據(jù)自己的字節(jié)序決定需不需要處理(小端轉(zhuǎn)換,大端不處理)。
在做網(wǎng)絡(luò)編程的時(shí)候,使用提供的庫(kù)即可進(jìn)行轉(zhuǎn)換(linux庫(kù),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ù)
如果平臺(tái)沒(méi)有提供這套,那么可以自己實(shí)現(xiàn)一下,原理很簡(jiǎ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);
}測(cè)試
#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下的測(cè)試結(jié)果如下圖

以上就是C++實(shí)現(xiàn)主機(jī)字節(jié)序和網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換示例的詳細(xì)內(nèi)容,更多關(guān)于C++主機(jī)網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)數(shù)組元素排序方法詳解
這篇文章主要為大家介紹了C語(yǔ)言算法練習(xí)中數(shù)組元素排序的實(shí)現(xiàn)方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語(yǔ)言有一定幫助,需要的可以參考一下2023-02-02
C語(yǔ)言基于EasyX庫(kù)實(shí)現(xiàn)有圖形界面鐘表
這篇文章主要介紹了C語(yǔ)言基于EasyX庫(kù)實(shí)現(xiàn)有圖形界面鐘表,直線轉(zhuǎn)動(dòng)端點(diǎn)計(jì)算,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
解決pip?install?dlib報(bào)錯(cuò)C++11?is?required?to?use?dlib
這篇文章主要介紹了在使用pip?install?dlib安裝dlib的時(shí)候報(bào)錯(cuò)C++11?is?required?to?use?dlib的解決方法,需要的的小伙伴可以參考一下,希望對(duì)你有所幫助2022-02-02
C++ map與set封裝實(shí)現(xiàn)過(guò)程講解
set set是一種關(guān)聯(lián)式容器,下面這篇文章主要給大家介紹了關(guān)于C++中map和set使用的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-03-03
C++字符數(shù)組的輸入輸出和字符串結(jié)束標(biāo)志使用講解
這篇文章主要介紹了C++字符數(shù)組的輸入輸出和符串結(jié)束標(biāo)志使用講解,是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09
Qt QFtp客戶(hù)端實(shí)現(xiàn)上傳下載文件
本文主要介紹了Qt QFtp客戶(hù)端實(shí)現(xiàn)上傳下載文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
C++實(shí)現(xiàn)LeetCode(109.將有序鏈表轉(zhuǎn)為二叉搜索樹(shù))
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(109.將有序鏈表轉(zhuǎn)為二叉搜索樹(shù)),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
淺談C++ Explicit Constructors(顯式構(gòu)造函數(shù))
下面小編就為大家?guī)?lái)一篇淺談C++ Explicit Constructors(顯式構(gòu)造函數(shù))。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12

