网络地址格式及域名地址转化

小灰灰 2022-08-20 07:18 299阅读 0赞

网络地址格式转化

通常用户在表达地址时采用的是点分十进制表示的数值(或者是为冒号分开的十进制Ipv6地址),而在通常使用的socket编程中使用的则是32位的网络字节序的二进制值,这就需要将这两个数值进行转换。

这里在Ipv4中用到的函数有inet_aton()、inet_addr()和inet_ntoa(),而IPV4和Ipv6兼容的函数有inet_pton()和inet_ntop()。
IPv4的函数原型:

  1. #include <sys/socket.h>
  2. #include <netinet/in.h>
  3. #include <arpa/inet.h>
  4. int inet_aton(const char *straddr, struct in_addr *addrptr);
  5. char *inet_ntoa(struct in_addr inaddr);
  6. in_addr_t inet_addr(const char *straddr);

函数inet_aton():将点分十进制数的IP地址转换成为网络字节序的32位二进制数值。
返回值:成功,则返回1,不成功返回0.

参数说明
参数straddr:存放输入的点分十进制数IP地址字符串。
参数addrptr:传出参数,保存网络字节序的32位二进制数值。
函数inet_ntoa():将网络字节序的32位二进制数值转换为点分十进制的IP地址。
函数inet_addr():功能与inet_aton相同,但是结果传递的方式不同。inet_addr()若成功则返回32位二进制的网络字节序地址。
IPv4和IPv6的函数原型:

  1. #include <arpa/inet.h>
  2. int inet_pton(int family, const char *src, void *dst);
  3. const char *inet_ntop(int family, const void *src, char *dst, socklen_t len);

函数inet_ptoninet_aton实现的功能类似,只是多了family参数,该参数指定为AF_INET,表示是IPv4协议,如果是AF_INET6,表示IPv6协议。
函数inet_ntopinet_ntoa类似,其中len表示表示转换之后的长度(字符串的长度)。


转换实例:

  1. #include <stdio.h>
  2. #include <sys/socket.h>
  3. #include <netinet/in.h>
  4. #include <arpa/inet.h>
  5. int main()
  6. {
  7. char ip[] = "192.168.121.128";
  8. int iRet;
  9. struct in_addr myaddr;
  10. inet_aton(ip, &myaddr);
  11. printf("myaddr.s_addr = %x\n", myaddr.s_addr);
  12. printf("inet_addr(ip) = %x\n", inet_addr(ip));
  13. /* inet_pton */
  14. iRet = inet_pton(AF_INET, ip, &myaddr);
  15. printf("myaddr.s_addr = %x\n", myaddr.s_addr);
  16. myaddr.s_addr = 0xac100ac4;
  17. /* inet_ntoa */
  18. printf("inet_ntoa(myaddr) = %s\n", inet_ntoa(myaddr));
  19. /* inet_ntop */
  20. inet_ntop(AF_INET, &myaddr, ip, 16);
  21. printf("ip = %s\n", ip);
  22. return 0;
  23. }

执行结果

  1. myaddr.s_addr = 8079a8c0
  2. inet_addr(ip) = 8079a8c0
  3. myaddr.s_addr = 8079a8c0
  4. inet_ntoa(myaddr) = 196.10.16.172
  5. ip = 196.10.16.172

域名地址转化

通常,人们在使用过程中都不愿意记忆冗长的IP地址,尤其到Ipv6时,地址长度多达128位,那时就更加不可能一次性记忆那么长的IP地址了。
使用主机名或域名将会是很好的选择。
主机名与域名的区别:主机名通常在局域网里面使用,通过/etc/hosts文件,主机名可以解析到对应的ip;域名通常是再internet上使用。
众所周知,百度的域名为:www.baidu.com,而这个域名其实对应了一个百度公司的IP地址,那么百度公司的IP地址是多少呢?
我们可以利用ping www.baidu.com来得到百度公司的ip地址。那么,系统是如何将www.baidu.com 这个域名转化为IP地址220.181.111.148的呢?

在linux中,有一些函数可以实现主机名和地址的转化,最常见的有gethostbyname()、gethostbyaddr()等,它们都可以实现IPv4和IPv6的地址和主机名之间的转化。
其中gethostbyname()是将主机名转化为IP地址,gethostbyaddr()则是逆操作,是将IP地址转化为主机名。

函数原型:

  1. #include <netdb.h>
  2. struct hostent* gethostbyname(const char* hostname);
  3. struct hostent* gethostbyaddr(const char* addr, size_t len, int family);

hostent结构体:

  1. struct hostent
  2. {
  3. char *h_name; /*正式主机名*/
  4. char **h_aliases; /*主机别名*/
  5. int h_addrtype; /*主机IP地址类型 IPv4为AF_INET*/
  6. int h_length; /*主机IP地址字节长度,对于IPv4是4字节,即32位*/
  7. char **h_addr_list; /*主机的IP地址列表*/
  8. }
  9. #define h_addr h_addr_list[0] /*保存的是ip地址*/

函数gethostbyname():用于将域名(www.baidu.com)或主机名转换为IP地址。
参数hostname指向存放域名或主机名的字符串。


程序实例(联网下操作)

  1. /*getAddr.c*/
  2. #include <netdb.h>
  3. #include <sys/socket.h>
  4. #include <stdio.h>
  5. int main(int argc, char *argv[])
  6. {
  7. if(argc != 2){
  8. printf("args err\n");
  9. }
  10. char *ptr, **pptr;
  11. struct hostent *hptr;
  12. char str[32] = {
  13. '\0'};
  14. /*ptr为要解析的域名或主机名*/
  15. ptr = argv[1];
  16. /*得到主机名字和地址信息的指针*/
  17. if((hptr = gethostbyname(ptr)) == NULL){
  18. printf("gethostbyname err\n");
  19. return 0;
  20. }
  21. printf("规范主机名为: %s\n", hptr -> h_name);
  22. /*打印别名*/
  23. for(pptr = hptr->h_aliases; *pptr != NULL; pptr++){
  24. printf("别名:%s\n", *pptr);
  25. }
  26. switch(hptr->h_addrtype){
  27. case AF_INET:
  28. case AF_INET6:
  29. pptr = hptr->h_addr_list;
  30. /* 将刚才得到的所有地址都打印*/
  31. for(; *pptr!=NULL; pptr++){
  32. printf(" address:%s\n", (char*)inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
  33. }
  34. printf(" first address: %s\n", (char*)inet_ntop(hptr->h_addrtype, hptr->h_addr, str, sizeof(str)));
  35. break;
  36. default:
  37. printf("未知地址类型\n");break;
  38. }
  39. return 0;
  40. }

程序编译及执行结果:

  1. yu@ubuntu:~/Linux/214/baidu$ ls
  2. getAddr.c
  3. yu@ubuntu:~/Linux/214/baidu$ gcc -o getAddr getAddr.c
  4. yu@ubuntu:~/Linux/214/baidu$ ./getAddr www.baidu.com
  5. 规范主机名为: www.a.shifen.com
  6. 别名:www.baidu.com
  7. address:14.215.177.38
  8. address:14.215.177.37
  9. first address: 14.215.177.38
  10. yu@ubuntu:~/Linux/214/baidu$ ./getAddr www.12306.com
  11. 规范主机名为: fw.ename.net
  12. 别名:www.12306.com
  13. address:198.148.92.57
  14. address:198.148.92.56
  15. address:198.148.92.58
  16. first address: 198.148.92.57

发表评论

表情:
评论列表 (有 0 条评论,299人围观)

还没有评论,来说两句吧...

相关阅读

    相关 域名网络地址

    域名系统 DNS(Domain Name System :域名系统)是对IP地址和域名进行相互转换的系统,其核心是DNS服务器。 什么是域名 提供网络服

    相关 MAC地址格式

    随机配置一个mac地址,发现有的会报出Cannot assign requested address。 错误码是EADDRNOTAVAIL。 检查不是组播地址也不是全0地址