地址结构介绍
IPV4地址结构
1 2 3 4 5 6 7 8 9 10
| struct in_addr { in_addr_t s_addr; }
struct sockaddr_in { sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; char sin_zero[8]; }
|
- IPV4地址结构至少16字节
- sin_port端口号和sin_addr_t地址均以网络字节序存储
- struct in_addr结构体的历史:为什么这个结构体就一个成员还使用结构体呢?早期版本将
struct in_addr
定义为多种结构的联合(union),方便访问32位地址中的每个字节,这在使用ABC类地址时非常方便,随着子网划分技术和无类地址编排的出现,这个联合已经不需要了,所以struct in_addr中仅剩下了一个成员。
通用套接字地址
socket各种函数传参时,需要兼容各类地址结构,所以使用通用套接字地址进行类型转换
1 2 3 4
| struct sockaddr { sa_family_t sa_family; char sa_data[14]; }
|
大小端转换函数
x86架构都是小端模式,而网络协议是大端模式,并且Linux下网络编程的系统调用中也有使用网络字节序的参数,所以大小端转换非常有必要
功能 |
函数 |
主机字节序转换成网络字节序 |
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort); |
网络字节序转换成主机字节序 |
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
|
地址转换函数
inet_aton
1 2 3
| int inet_aton(const char *cp, struct in_addr *inp); 功能:将cp指向的点分十进制字符串转换为网络字节序的32位地址 成功返回1,失败返回0
|
inet_ntoa
1 2
| char *inet_ntoa(struct in_addr in); 功能:将网络字节序的32位地址转换为点分十进制字符串,通过返回值返回
|
inet_addr
1 2 3
| in_addr_t inet_addr(const char *cp); 功能:将cp指向的点分十进制字符串转换为网络字节序的32位地址,通过返回值返回 注意:该函数出错时返回INADDR_NONE,该宏32位均位1,这意味着255.255.255.255不能由该函数转换,尽量不要使用该函数
|
inet_pton
1 2 3 4
| int inet_pton(int family,const char *strptr, void *addrptr); 功能:将strptr指向的点分十进制数串转换成网络字节序的32位地址, family指定协议:AF_INET或AF_INET6 成功返回1,失败返回0
|
inet_ntop
1 2 3 4 5 6 7 8 9
| const char *inet_ntop(int family,const void *addrptr,char *strptr, size_t len); 功能:将addrptr指向的网络字节序的32位地址转换成点分十进制数串 len指出了strptr的空间大小,其取值如下 #define INET_ADDRSTRLEN 16 #define INET6_ADDRSTRLEN 46 因为ip地址的字符串最多有15位,最后还有一个'\0',所以注意使用这个函数的时候空间要+1 成功返回strptr的地址,失败返回NULL
|