这两个专用socket地址结构体各字段的含义很明确 。
所有专用socket地址(以及sockaddr_storage)类型的变量在实际使用时都需要转化为通用socket地址类型sockaddr(强制转化即可),因为所有socket编程接口使用的地址参数的类型都是sockaddr 。
IP地址转换函数通常,人们习惯用可读性好的字符串来表示IP地址,比如用点分十进制字符串表示IPv4地址,以及用十六进制字符串表示IPv6地址 。但编程中我们需要先把它们转化为整数(二进制数)方能使用 。而记录日志则相反,我们要把整数表示的IP地址转化为可读的字符串 。
下面3个函数可用于用点分十进制字符串表示的字符串表示的IPv4地址和用网络字节序整数表示的IPv4地址之间转换:
#include <arpa/inet.h>inet_addr函数将用点分十进制串表示的IPv4地址转化为用网络字节序整数表示的IPv4地址 。失败返回INADDR_NONE 。
in_addr_t inet_addr(const char * strptr);
int inet_aton(const char *cp, struct in_addr *inp);
char *inet_ntoa(struct in_addr in);
inet_aton函数完成和inet_addr同样的功能,但是将转化结果存储与参数inp指向的地址结构中 。它成功返回1,失败则返回0 。
inet_ntoa函数将用网络字节序整数表示的IPv4地址转换为用点分十进制字符串表示的IPv4地址 。但需要注意的是:该函数内部用一个静态变量存储转化结果,函数的返回值指向该静态内存,因此inet_ntoa是不可重入的 。
#include <stdio.h>#include <arpa/inet.h>int main(int argc, char const *argv[]){char ip1[] = "1.2.3.4";char ip2[] = "10.194.71.60";struct in_addr inAddr1;struct in_addr inAddr2;inet_aton(ip1, &inAddr1);inet_aton(ip2, &inAddr2);char *szValue1 = inet_ntoa(inAddr1);char *szValue2 = inet_ntoa(inAddr2);printf("address1: %sn", szValue1);printf("address2: %sn", szValue2);return 0;}
文章插图
不可重入的inet_ntoa函数实验结果
下面这对更新的函数也能完成和前面3和函数一样的功能,并且它们使用适用于IPv4地址和IPv6地址:
#include <arpa/inet.h>inet_pton函数将用于字符串表示的IP地址src(用点分十进制字符串表示的IPv4地址或用十六进制字符串表示的IPv6地址)转换成用网络字节序整数表示的IP地址,并把转换结果存储于dst指向的内存中 。其中,af参数指定地址族:
int inet_pton(int af, const char* src, void *dst);
const char* inet_ntop(int af, const void* src, char* dst, socklen_t cnt);
- AF_INET
- AF_INET6
inet_ntop函数进行相反的转换,前三个参数的含义与inet_pton参数相同,最后一个cnt指定目标存储单元的大小 。下面两个宏能帮助我们指定这个大小(分别用于IPv4和IPv6):
#include <netinet/in.h>inet_ntop成功时返回目标存储单元的地址,失败返回NULL并设置errno 。
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>int main(){char *ipv4 = "10.0.0.200";char *ipv6 = "fe80::4bde:83d8:dbcf:72f3";in_addr inAddr4;in6_addr inAddr6;inet_pton(AF_INET, ipv4, &inAddr4);inet_pton(AF_INET6, ipv6, &inAddr6);char addr1[INET_ADDRSTRLEN];char addr2[INET6_ADDRSTRLEN];if(addr1 == inet_ntop(AF_INET, (void *)&inAddr4, addr1, INET_ADDRSTRLEN)){printf("truen");}printf("IPv4 addr: %sn", inet_ntop(AF_INET, (void *)&inAddr4, addr1, INET_ADDRSTRLEN));printf("IPv4 addr: %sn", inet_ntop(AF_INET6, (void*)&inAddr6, addr2, INET6_ADDRSTRLEN));return 0;}
文章插图
【Linux网络API - socket地址API】
推荐阅读
- Kali linux 安装教程
- Linux操作系统的作业调度和进程调度
- 开启天文之路的 4 个 Python 工具 | Linux 中国
- 寒露是什么意思,网络白茶是什么意思
- linux xshell 免密登录及排错
- Linux操作系统中常用调度算法
- Linux 常用命令大汇集
- 网络扫描利器Fing之Linux版本使用教程
- linux安装mysql启动不起来总结
- GCNN 使用Keras构建具有自定义结构和层次的图卷积神经网络
