我正在使用http://www.kutukupret.com/2009/09/28/gethostbyname-vs-getaddrinfo/中找到的这段代码来执行dns查找
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[ ]) {
struct hostent *h;
/* error check the command line */
if(argc != 2) {
fprintf(stderr, "Usage: %s hostname\n", argv[0]);
exit(1);
}
/* get the host info */
if((h=gethostbyname(argv[1])) == NULL) {
herror("gethostbyname(): ");
exit(1);
}
else
printf("Hostname: %s\n", h->h_name);
printf("IP Address: %s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));
return 0;
}
我面临一个奇怪的事实
./test www.google.com
Hostname: www.l.google.com
IP Address: 209.85.148.103
工作正常,但如果我尝试解析一个不完整的IP地址,我会得到这个
./test 10.1.1
Hostname: 10.1.1
IP Address: 10.1.0.1
我希望会出现如下错误
./test www.google
gethostbyname(): : Unknown host
但该计划似乎有效。
知道为什么吗?
答案 0 :(得分:18)
这不是bug,而是inet_aton()函数的一个特性:
说明
inet_aton()函数转换指定的字符串 Internet标准点表示法,到网络地址,并存储 提供的结构中的地址。
使用点表示法指定的值采用以下形式之一:
a.b.c.d 当指定了四个部分时,每个部分都被解释为一个数据字节,并从左到右分配到一个互联网地址的四个字节。
<强> A.B.C 强> 当指定三部分地址时,最后一部分被解释为16位数量并放在网络地址的最右边两个字节中。这使得三部分地址格式便于将B类网络地址指定为128.net.host。
例如,您可以阅读有关此there的更多信息。
答案 1 :(得分:7)
gethostbyname()的name参数应为节点名称;传递数字地址字符串时gethostbyname()的行为未指定。对于IPv4,数字地址字符串应采用inet_addr()中描述的点分十进制表示法。
因此,从POSIX的角度来看,在传递IP地址时你不能指望任何事情。
在我的系统上,man page说明了这一点:
如果name是IPv4或IPv6地址,则不执行查找,gethostbyname()只是将name复制到h_name字段,并将其结构in_addr等效到返回的hostent结构的h_addr_list [0]字段中。
如果你传递一个不完整的IP地址,它没有说明会发生什么,所以任何事情都可能发生,包括你观察到的行为。
有关如何在系统上实施gethostbyname
的更多信息,您可以查看文档中的功能和/或源代码(如果有)。