网络字节序和本地字节序之间转换
目录当我们与同一台计算机的进程进行通信时,一般不用考虑字节序。什么是字节序——字节序是一个处理器架构特性,用于指示像整数这样的大数据类型内部的字节如何排序。
考虑一个16位整数,它由2个字节组成。内存中存储这两个字节有2种方法:一种是将低序字节存储在起始地址,这称为小 端字节序;另一种方法 是将高 字节序存储在起始地址,这称为大端字节序。
主机字节序
这两种字节序之间没有标准可循,两种格式都有系统使用。有些处理器可以配置成大端的,也可以配置成小端的。我们把某个给定系统所使用的字节序称为主机字节序。
网络字节序
网络协议指定了字节序,因此异构计算机系统能够交换协议信息而不会被字节序所混淆。TCP/IP协议栈使用大端字节序。应用程序交换格式化数据时,字节序问题就 会出现。对于TCP/IP,地址用网络字节序来表示,所以应用程序有时需要在处理器的字节序与网络字节序之间转换它们。
相关函数htons
, htonl
, ntohs
, 和 ntohl
为了统一发送数据的格式,所以互联网传输的数据统一采用大端方式,为了方便开发,linux系统提供了转换的接口:htonl、htons、ntohl、ntohs。 h :host (主机/本地)、to: (转换)、n :net(网络)、l :long(长整型)、s :short (短整型)
这些函数用于在主机字节序和网络字节序之间转换16位或32位数值。htons
和htonl
用于将主机字节序的值转换为网络字节序,而ntohs
和ntohl
则相反,用于将网络字节序的值转换为主机字节序。这些转换在网络通信中非常重要,因为不同的机器可能有不同的字节序,而网络协议通常使用网络字节序。
#include <netinet/in.h>
// htons - 主机字节序转网络字节序(16位)
uint16_t htons(uint16_t host16bitvalue);
// htonl - 主机字节序转网络字节序(32位)
uint32_t htonl(uint32_t host32bitvalue);
// ntohs - 网络字节序转主机字节序(16位)
uint16_t ntohs(uint16_t net16bitvalue);
// ntohl - 网络字节序转主机字节序(32位)
uint32_t ntohl(uint32_t net32bitvalue);
函数表格
函数名 | 描述 | 参数 | 返回值 | 用法 |
---|---|---|---|---|
htonl() | 主机字节序转网络字节序(32位) | uint32_t hostlong :本地字节序的32位数 |
网络字节序的32位数 | 用于将IPv4地址从主机字节序转换为网络字节序 |
htons() | 主机字节序转网络字节序(16位) | uint16_t hostshort :本地字节序的16位数 |
网络字节序的16位数 | 用于将端口号从主机字节序转换为网络字节序 |
ntohl() | 网络字节序转主机字节序(32位) | uint32_t netlong :网络字节序的32位数 |
本地字节序的32位数 | 用于将IPv4地址从网络字节序转换为主机字节序 |
ntohs() | 网络字节序转主机字节序(16位) | uint16_t netshort :网络字节序的16位数 |
本地字节序的16位数 | 用于将端口号从网络字节序转换为主机字节序 |
相关函数inet_aton
, inet_ntoa
, inet_pton
, 和 inet_ntop
af
参数代表地址族,对于IPv4是AF_INET
,对于IPv6是AF_INET6
。src
和dst
分别代表源地址字符串和目标地址结构。inet_pton
和inet_ntop
是更现代的函数,它们支持IPv6地址的转换。
#include <arpa/inet.h>
// inet_aton - 将点分十进制的IP地址转换为网络字节序的二进制形式
int inet_aton(const char *cp, struct in_addr *inp);
// inet_ntoa - 将网络字节序的二进制IP地址转换为点分十进制的字符串形式
char *inet_ntoa(struct in_addr in);
// inet_pton - 将点分十进制的IP地址转换为网络字节序的二进制形式
int inet_pton(int af, const char *src, void *dst);
// inet_ntop - 将网络字节序的二进制IP地址转换为点分十进制的字符串形式
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
函数表格
函数名 | 描述 | 参数 | 返回值 | 用法 |
---|---|---|---|---|
inet_aton | 将点分十进制的IP地址转换为网络字节序的二进制结构 | const char *cp :点分十进制的IP地址字符串struct in_addr *inp :存储转换后的IP地址 |
成功时返回非零值,失败时返回0 | 用于IPv4地址转换,现已较少使用,推荐使用inet_pton |
inet_ntoa | 将网络字节序的二进制IP地址转换为点分十进制的字符串 | struct in_addr in :网络字节序的IP地址结构 |
点分十进制的IP地址字符串 | 用于IPv4地址转换,现已较少使用,推荐使用inet_ntop |
inet_pton | 将点分十进制的IP地址转换为网络字节序的二进制结构 | int af :地址族(如AF_INET 或AF_INET6 )const char *src :IP地址字符串void *dst :存储转换后的IP地址 |
成功时返回1,输入不是有效的地址格式时返回0,出错时返回-1 | 支持IPv4和IPv6地址转换,是inet_aton 的更通用和安全的替代品 |
inet_ntop | 将网络字节序的二进制IP地址转换为点分十进制的字符串 | int af :地址族(如AF_INET 或AF_INET6 )const void *src :网络字节序的IP地址char *dst :存储转换后的IP地址字符串socklen_t size :目标存储空间的大小 |
成功时返回指向结果的指针,失败时返回NULL | 支持IPv4和IPv6地址转换,是inet_ntoa 的更通用和安全的替代品 |
这些函数之间的主要区别在于它们处理的数据类型和转换的方向。
inet_ntoa()
、inet_aton()
专门用于IPv4地址的字符串表示,而其他四个函数用于通用的数值类型的字节序转换。
inet_pton()
和 inet_ntop()
,这两个函数支持IPv4和IPv6地址的转换,用于点分十进制的字节转换。
inet_pton()
用于将点分十进制的IP地址转换为网络字节序的二进制形式,
inet_ntop()
用于将网络字节序的二进制IP地址转换为点分十进制的字符串形式