1、背景
“端口号”或者“点分十进制的IP”必须先转化为“网络字节序”,才能在网络环境中传输。
TCP/IP 规定,网络数据流采用大端字节序:高地址存低位数据,计算机一般采用小端存储。如下图所示:
因此,从计算机到网络,需要一个“主机字节序”到“网络字节序”的转换。
2、转换函数
符号说明:
32:32 位,代表转IP ;
16:代表转端口号 ;
h:host 主机 ;
to:到;
n:net 网络 ;
l:长整形(标识 IP) ;
s:短整形(标识端口号)。
(1)端口号转换:
#include <arpa/inet.h> // 头文件
uint16_t htons(uint16_t hostshort); // 端口号 本地字节序转网络字节序
uint16_t ntohs(uint16_t netshort); // 端口号 网络字节序转本地字节序
(2)IP地址转换
uint32_t htonl(uint32_t hostlong); // IP 本地字节序转网络字节序
uint32_t ntohl(uint32_t netlong); // IP 网络字节序转本地字节序
但是,使用以上函数转换 IP 时候,应用起来比较麻烦,需要:先将点分十进制(字符串)转为unsigned int(本地字节序) 然后再利用上述函数转为网络字节序。
因此,一般只这样使用:
htonl(INADDR_ANY); // 将本地的任意有效的 IP转为网络字节序
彻底解决方式:常用以下函数进行转换 IP,这样可以实现:字符串直接转换为网络字节序
#include <arpa/inet.h> // 头文件
int inet_pton(int af, const char *src, void *dst); // 点分十进制直接转为网络字节序,成功返回0,失败返回-1
参数:
af:指定 IP 版本 :AF_INET为IPv4 、AF_INET6为IPv6
src:点分十进制的 IP 地址
dst:传出参数,获得的网络字节序,
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); // 网络字节序直接转点分十进制
参数:
src:网络字节序
dst:传出参数,点分十进制字符串的首地址
size:socklen_t 类型,字符串的长度