网络字节序与主机字节序的转换函数实践
网络字节序与主机字节序的转换函数实践
在Linux网络编程中,经常碰到网络字节序与主机字节序的相互转换。说到网络字节序与主机字节序需要清晰了解以下几个概念。
主机字节序
字节序,是字节在电脑中存放时的序列与输入(输出)时的序列是先到的在前还是后到的在前。比如一个int32_t类型的数值占用4个字节,这4个字节在内存中的排列顺序就是字节序。字节序可以分为两种:
(1)小端字节序(Little endinan),数值低位存储在内存的低地址,高位存储在内存的高地址;
(2)大端字节序(Big endian),数值高位存储在内存的低地址,低位存储在内存的高地址。
以32位位宽数值0x12345678为例,小端字节序与大端字节序具体的存储区别如下所示:
小端模式优点 :
强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
大端模式优点 :
符号位的判定固定为第一个字节,容易判断正负。
网络字节序
网络数据流也有大小端之分。
网络数据流的地址规定:先发出的数据是低地址,后发出的数据是高地址。发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出,为了不使数据流乱序,接收主机也会把从网络上接收的数据按内存地址从低到高的顺序保存在接收缓冲区中。TCP/IP协议规定:网络数据流应采用大端字节序,即低地址高字节。
大小端转换
常用的转换函数:
函数原型 | 函数说明 |
---|---|
uint16_t htons(uint16_t hostshort); | 将 16 位的主机字节序转换为网络字节序 |
uint32_t htonl(uint32_t hostlong); | 将 32 位的主机字节序转换为网络字节序 |
uint16_t ntohs(uint16_t netshort); | 将 16 位的网络字节序转换为主机字节序 |
uint32_t ntohl(uint32_t netlong); | 将 32 位的网络字节序转换为主机字节序 |
其中
- uint16_t:无符号的 16 位整数(等同于 unsigned short)
- uint32_t:无符号的 32 位整数(等同于 unsigned int)
点击这里,通过以下代码可以查看自己电脑是大端还是小端
#include<stdio.h>
int main(int argc, char** argv)
{
union {
short s;
char c[sizeof(short)];
} un;
un.s = 0x0102;
if (sizeof(short) == 2) {
if (un.c[0] == 1 && un.c[1] == 2)
printf("big-endian\n");
else if (un.c[0] == 2 && un.c[1] == 1)
printf("little-endian\n");
else
printf("unknown\n");
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构