C++實(shí)現(xiàn)主機(jī)字節(jié)序和網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換示例
字節(jié)序問題
現(xiàn)代CPU一次至少能裝載4字節(jié)(32位機(jī)),即一個(gè)整數(shù),這4個(gè)字節(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ù)需要在兩臺(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í)候,使用提供的庫即可進(jìn)行轉(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ù)
如果平臺(tái)沒有提供這套,那么可以自己實(shí)現(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++實(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++ 調(diào)用 QML 回調(diào)方法的完整實(shí)現(xiàn)
在 Qt 6 開發(fā)中,C++ 與 QML 混合編程是常見場景,當(dāng) C++ 處理異步操作時(shí),需要將結(jié)果通知給 QML 界面,回調(diào)函數(shù)是最直觀的通信方式之一,下面小編就和大家詳細(xì)講講具體的調(diào)用實(shí)現(xiàn)方法吧2025-11-11
C++ std::condition_variable 條件變量用法解析
condition_variable(條件變量)是 C++11 中提供的一種多線程同步機(jī)制,它允許一個(gè)或多個(gè)線程等待另一個(gè)線程發(fā)出通知,以便能夠有效地進(jìn)行線程同步,這篇文章主要介紹了C++ std::condition_variable 條件變量用法,需要的朋友可以參考下2023-09-09
C語言實(shí)現(xiàn)簡易停車場管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)簡易停車場管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03

