我在套接字上找到了this C教程,我遇到了这段代码:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
int main(int argc, char *argv[]) {
char *hostname = "www.google.com";
char ip[100];
struct hostent *he;
struct in_addr **addr_list;
int i;
if ((he = gethostbyname(hostname)) == NULL) {
herror("gethostbyname");
return 1;
}
addr_list = (struct in_addr **) he->h_addr_list;
for (i = 0; addr_list[i] != NULL; i++) {
strcpy(ip, inet_ntoa(*addr_list[i]));
}
printf("%s resolved to: %s\n", hostname, ip);
return 0;
}
对我来说似乎无用的部分是:
addr_list = (struct in_addr **) he->h_addr_list;
for (i = 0; addr_list[i] != NULL; i++) {
strcpy(ip, inet_ntoa(*addr_list[i]));
}
如果是这样的话,对我来说会更有意义:
for (i = 0; he->h_addr_list[i] != NULL; i++) {
strcpy(ip, he->h_addr_list[i]);
}
所以我尝试了这个,它编译得很好,但是当我运行它时输出:
www.google.com resolved to: J}�
但预期的输出是:www.google.com resolved to: 74.125.225.17
我不知道为什么必须将he->h_addr_list
(char **)
类型转换为(struct in_addr **)
,然后才将每个地址转换回(char **)
。< / p>
为什么这是必要的,对我来说似乎很奇怪。另外,为什么我的版本的输出都很奇怪?
答案 0 :(得分:1)
h_addr_list
的类型是char**
,因为它指向恰好包含互联网地址的任意缓冲区。
互联网地址采用原始数字形式 - 例如,普通的IPv4地址适合32位整数。 (x.x.x.x,其中每个x为0-255 == 8位)
要将数字表单转换为您可以使用的字符串表单,您需要将地址传递给inet_ntoa
。它为您格式化地址。
不幸的是,h_addr_list
的类型与该调用不兼容,强制进行强制转换。如果要再次执行h_addr_list
的类型,可能会以不需要强制转换的方式设置。