https://www.cnblogs.com/zhangsanlisi411/p/16771554.html
1 前言知识
字节序指的是计算机多于一个字节时数据在内存中的存储顺序,例如一个int
由四个字节组成,内存中存储有两种方式:
- 小端字节序:低字节在低地址(0x12794468, 其中68为低字节),高字节在高地址
- 大端字节序:高字节在低地址,低字节在高地址。
将0x12345678
放入内存,如下图:
1.1 主机字节序和网络字节序
网络字节序:网络字节序是固定的,它与具体的CPU类型、操作系统等无关。网络字节序采用大端字节排序。
主机字节序:不同的机器主机字节序可能不同,与CPU设计有关,数据的顺序是由CPU决定的,而与操作系统无关。
由于主机字节序的不同,数据从主机 A 到主机 B 的过程中,需要有一个标准化的过程(其标准化过程为将主机字节序转化为网络字节序)。如下图:
判断本机字节序时就可以使用前面介绍的方法:
//@ret:0:小端字节序,1:大端字节序
int dGetHostByteOrder()
{
uint32_t a = 0x12345678;
uint8_t *p = (uint8_t *)&a;
if(*p==0x78) {
return 0;
}
else {
return 1;
}
}
2 网络字节序和主机字节序的转换
linux编程中有以下四个标准库进行字节序的转换
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong); //把uint32_t类型从主机序转换到网络序
uint16_t htons(uint16_t hostshort); //把uint16_t类型从主机序转换到网络序
uint32_t ntohl(uint32_t netlong); //把uint32_t类型从网络序转换到主机序
uint16_t ntohs(uint16_t netshort); //把uint16_t类型从网络序转换到主机序
传输字符串时并不需要网络字节序和主机字节序的转换,因为发送字符串"Hello"
时,需要将其转换为字节数组
[72, 101, 108, 108, 111]
,每个字符占一个字节,一个字节并不涉及大端和小端存储的争议。
2.1 网络编程中的转换函数
/***********************************************
* @brief: 将点分IP地址转换为二进制网络字节序IP地址,包含V4和V6
* @af:地址簇
* @src:转换前IP地址
* @dst:转换后IP地址
*************************************************/
int inet_pton(int af, const char *src, void *dst);
/*********************************************************************
* af:地址族(address family),可以是 AF_INET(IPv4)或 AF_INET6(IPv6)。
* src:指向包含网络字节序IP地址的指针。
* dst:指向目标缓冲区的指针,该缓冲区用于存储转换后的字符串。
* size:目标缓冲区的大小。
* 如果转换成功,inet_ntop() 返回指向目标缓冲区的指针;如果失败,返回 NULL。
**************************************************************************/
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);