说在前面
- 环境: ubuntu16.04
- 参考: UNIX网络编程
数据类型说明
数据类型 | 说明 | 头文件 |
size_t | 无符号整形,与机器相关,32位中为unsigned int,64位为unsigned long long | <stddef.h> |
in_addr_t | IPv4地址,一般为uint32_t | <netinet/in.h> |
啥
- 网际地址ASCII字符串形式(如IPv4的“192.168.192.1”)与网络字节序的二进制形式之间的转换函数。
inet_aton、inet_addr 、inet_ntoa
- 用于IPv4地址
- 定义
inet_ntoa函数在实现时,其返回值所指向的字符串是存放在静态内存中,该函数是不可重入的。#include <arpa/inet.h> /* * 功能: 将字符串形式的IPv4地址转换并存储到结构体struct in_addr中 * 返回值:若字符串有效则返回1;否则0 * 其他: 若addrptr指针为空,函数对字符串进行检查(是否为正确的IP地址),但是不存储。 */ int inet_aton(const char *strptr, struct in_addr *addrptr); /* * 功能: 将字符串形式的IPv4地址转换32位二进制网络序IPv4地址 * 返回值:若字符串有效则返回32位二进制网络序IPv4地址; * 否则返回INADDR_NONE(通常是32位均为1的值); * 其他: 由于INADDR_NONE的存在,导致无法处理255.255.255.255;该函数已被废弃 */ in_addr_t inet_addr(const char *strptr); /* * 返回值:指向点分十进制字符串的指针 */ char *inet_ntoa(struct in_addr inaddr);
- 示例
#include <stdio.h> #include <arpa/inet.h> int main() { struct in_addr addr; char test_str[] = "192.168.2.1"; if (inet_aton(test_str, &addr) == 1) { printf("ASCII address: %s\n", test_str); printf("32bit net address: %02X\n", addr.s_addr); } else printf("bad ip address: %s\n", test_str); printf("\n"); addr.s_addr = 0x23152659; printf("32bit net address: %02X\n", addr.s_addr); printf("ASCII address: %s\n", inet_ntoa(addr)); return 0; }
inet_pton、inet_ntop
- 可用于IPv4、IPv6;p代表表达(presentation,通常是ASCII字符串),n代表数值(numeric,通常是存放于套接字地址结构中的二进制值)
- 定义
#include <arpa/inet.h> /* * 功能: 将字符串形式的IP地址转换对应的二进制值并存储到对应的套接字地址结构中 * 返回值:若成功则返回1; * 若输入的不是有效的IP格式则返回0; * 若出错则返回-1 * 其他: 参数family表示地址族,AFINET/AFINET6; * 若使用不支持的地址族,函数将返回错误并置errno为EAFNOSUPPORT */ int inet_pton(int family, const char *strptr, void *addrptr); /* * 功能: 将二进制值形式的IP地址转换为对应的ASCII字符串形式 * 返回值:若成功则返回指向结果的指针;出错返回NULL * 其他1: 参数family表示地址族,AFINET/AFINET6; * 若使用不支持的地址族,函数将返回错误并置errno为EAFNOSUPPORT * 其他2: 参数len表示目标存储单元(存储转换后的ASCII字符串)的大小; * 常用如INET_ADDRSTRLEN=16, INET_ADDRSTRLEN=46; * 若len值过小不足以容纳转换后的ASCII字符串,返回空指针,置errno为ENOSPC */ const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);
- 示例
#include <stdio.h> #include <string.h> #include <arpa/inet.h> int main() { struct in_addr addr; char test_str[] = "192.168.2.1"; if (inet_pton(AF_INET, test_str, &addr) == 1) { printf("ASCII address: %s\n", test_str); printf("32bit net address: %02X\n", addr.s_addr); } else printf("bad ip address: %s\n", test_str); printf("\n"); char temp_str[INET_ADDRSTRLEN+1]; addr.s_addr = 0x23152659; memset(temp_str, 0, sizeof(temp_str)); char *strptr; strptr = inet_ntop(AF_INET, &addr, temp_str, INET_ADDRSTRLEN); printf("32bit net address: %02X\n", addr.s_addr); printf("ASCII address: %s --%02X\n", strptr, (unsigned int)strptr); printf("ASCII address: %s --%02X\n", temp_str, (unsigned int)temp_str); return 0; }
协议无关
- 在《UNIX网络编程》一书中将上述函数进行封装,可以更加简单的进行调用,具体见代码