目录
1 主机字节序和网络字节序
1.1 什么是字节序?
1.2 查看主机字节序
2 字节序转换函数
3 IP地址字节序转换函数
4 练习
1 主机字节序和网络字节序
1.1 什么是字节序?
字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序,分为:
大端字节序 (Big endian)
小端字节序(Little endian)
示例: 0x11223344
一般主机当中使用小端字节序(因为涉及运算,先算低位再算高位)
网络通信当中必须使用大端字节序 (因为读起来方便,因为先读高位,再读低位)
1.2 查看主机字节序
uint32_t val32 = 0x11223344;
uint8_t val8 = *( (uint8_t *)&val32 );
if(val8 == 0x44)
printf("本机是小端字节序\n");
else
printf("本机是大端字节序\n");
- 定义了一个无符号32位整型变量val32,并且初始化为0x11223344
- 定义一个8位的无符号整型变量val8,并且将强转以后的val32的数据赋值给val8
- 这样做的目的是获取变量val32第一个字节的值,后面就可通过判断val8的值是0x44或者0x11来确定主机字节序是大端还是小端
ubuntu示例
#include <stdio.h>
int main(int argc, char *argv[])
{
unsigned int val32 = 0x11223344;
unsigned char val8 = *((unsigned char *)(&val32));
if(val8 == 0x44)
printf("本机是小端字节序\n");
else
printf("本机是大端字节序\n");
return 0;
}
2 字节序转换函数
//头文件
#include <arpa/inet.h>
//字节序转换函数
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
字节序转换函数
3 IP地址字节序转换函数
- IP地址可能会存在“点分十进制”的字符串形式,转换之前需要注意
- 主机字节序一般采用小端字节序
- 网络字节序转主机字节序以后通常需要转换成“点分十进制”的字符串
//字符串转32位数据
#include <arpa/inet.h>
//IP地址序转换函数
//将一个点分十进制的IPv4地址转换为一个32位的网络字节序的整数表示。
in_addr_t inet_addr(const char *cp);
//将一个点分十进制的IPv4地址转换为一个32位的网络字节序的整数,并存储到struct in_addr类型的结构体中。
int inet_aton(const char *cp, struct in_addr *addr);
//将一个点分十进制的IPv4或IPv6地址转换为对应地址族的二进制格式,并存储到指定的内存空间中。
int inet_pton(int af, const char *cp, void *addr);
//将一个32位的网络字节序的整数表示的IPv4地址,转换为以点分十进制表示的字符串形式。
char* inet_ntoa(struct in_addr in);
//将一个二进制格式的IPv4或IPv6地址转换为相应的点分十进制字符串形式,并存储到指定的内存空间中。
int inet_ntop(int af, const void *addr, char *cp);
//支持IPV6的地址转换函数
#include <arpa/inet.h>
//IP地址序转换函数
int inet_pton(int af, const char *cp, void *addr);
int inet_ntop(int af, const void *addr, char *cp);
4 练习
请简要总结网络字节序形成的原因,以及网络编程中对应的处理方法。
一般主机当中使用小端字节序(因为涉及运算,先算低位再算高位)
网络通信当中必须使用大端字节序 (因为读起来方便,因为先读高位,再读低位)
使用网络字节序可以确保数据在不同设备之间正确地传递。
htonl() 和 ntohl():32位 这两个函数用于在主机字节序和网络字节序之间进行转换。
htons() 和 ntohs():16位 这两个函数用于在主机字节序和网络字节序之间进行转换。