这个话题应该不属于c++,但是我们用c++编程经常会用到。本人做为一个软件工程师,曾经在调试的过程中遇到过大小端的bug。这个是工程中常见,但是不易察觉的bug。记得公司有一个团队连续通宵奋战一个月追查一个bug,结果就是大小端的问题。所以希望大家引以为戒。
什么是大小端(endianness)?
大小端是指多字节数据(如 int、float 等)在内存中字节的排列顺序。
- 大端(big-endian):高字节(most significant byte, msb)存放在低地址,低字节(least significant byte, lsb)存放在高地址。例如,整数 0x12345678 在内存中按地址递增顺序存储为:12 34 56 78。
- 小端(little-endian):低字节(lsb)存放在低地址,高字节(msb)存放在高地址。同样 0x12345678 存储为:78 56 34 12。
常见平台:x86、x86_64 架构通常为小端;网络协议(如 tcp/ip)规定使用大端(也叫网络字节序);arm 架构可配置为两种。
#include <iostream>
int main() {
int num = 0x12345678; // 32位整数
unsigned char* firstbyte = reinterpret_cast<unsigned char*>(&num);
std::cout << "memory bytes (low to high): ";
for (size_t i = 0; i < sizeof(num); ++i) {
std::cout << std::hex << static_cast<int>(firstbyte[i]) << " ";
}
std::cout << std::dec << std::endl; // 恢复十进制输出
if (firstbyte[0] == 0x78) {
std::cout << "this system is little-endian." << std::endl;
} else if (firstbyte[0] == 0x12) {
std::cout << "this system is big-endian." << std::endl;
} else {
std::cout << "unexpected byte order." << std::endl;
}
return 0;
}大小端字节序的问题
(1) 发送协议栈和接受协议栈必须就这些多字节段各个字节的传送顺序达成一致。网际协议使用大端字节序来传送这些多字节整数。函数如下:
#include <netinet/in.h>
uint16_t htons(uint16_t host16bitvalue);
uint32_t htonl(uint32_t host32bitvalue);
uint16_t ntohs(uint16_t net16bitvalue);
uint32_t ntohl(uint32_t net32bitvalue);(2) 当服务器和客户端的字节序不一样的时候,可能会出现这样的情况,当服务器向客户端传输遗传数字的时候,客户端解析出来的就可能不是这个数。比如下面:
#include "stdafx.h"
int main()
{
int port = 7777;
printf("port: %d\n", port);
printf("port to net: %d\n", htons(port));
getchar();
return 0;
}得到的结果如下:
port: 7777
port to net: 24862
大小端问题解决方法
(1) 如果客户端和服务器是相同的字节序,只是长整数格式不同,则可以采用字符串传输数据。
(2) 如果客户端和服务器是不同的字节序,可以显示的定义所支持数据类型的二进制格式,并以这样的格式在这两个之间传递。
到此这篇关于深入理解c++ 大小端字节序的文章就介绍到这了,更多相关c++ 大小端字节序内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论