我确信这是由于一个愚蠢的错误,但我在几个小时内一直在调整,我无法解决问题。
在我的程序中,我有一个函数返回给定域的地址。它调用getaddrinfo,将地址复制到新的dinamically asigned变量,将其指针设置为hostent结构并返回它。然而,返回的地址不正确。经过一些调整后,我意识到它的值在代码的某些方面意外地发生了变化。
我在本期杂志中制作了一个示例程序:
#include <iostream>
#include <string.h>
#include <string>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <stdlib.h>
using namespace std;
typedef unsigned long int longip_t;
int main(int argc, char** argv) {
struct addrinfo hints, *res;
struct hostent *final = new hostent;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
getaddrinfo("automation.whatismyip.com", "80", &hints, &res);
cout << inet_ntoa(((sockaddr_in*)res->ai_addr)->sin_addr) << endl;
in_addr *addr = new in_addr;
memcpy((void*)addr, (void*)(&((sockaddr_in*)res->ai_addr)->sin_addr), sizeof(in_addr));
cout << inet_ntoa(*addr) << endl;
final->h_addr_list = (char**)addr;
cout << inet_ntoa(*addr) << endl;
final->h_addr = (char*)addr; // At this point the value of addr changes
cout << inet_ntoa(*addr) << endl;
cout << inet_ntoa(*(in_addr*)final->h_addr_list) << endl;
exit(0);
}
我得到的输出:
72.233.89.195
72.233.89.195
72.233.89.195
48.116.218.9
48.116.218.9
前三个IP是正确的,但每次运行程序时,我得到最后两个IP的不同值。在将指针设置为hostent结构后,它看起来addr的值发生了变化。
答案 0 :(得分:3)
来自MSDN上的hostent
结构
h_addr_list 以NULL结尾的主机地址列表。 地址以网络字节顺序返回。宏 h_addr 是 定义为 h_addr_list [0] ,以便与旧软件兼容。
final->h_addr = (char*)addr;
所以上面这行真的是这个
final->h_addr_list[0] = (char*)addr;
从final->h_addr_list = (char**)addr;
,该行变为此
addr[0] = (char*)addr;
现在,我相信你看到了问题。 :)
<强> [更新] 强>
设置它的正确方法实际上是简单而自动的。您应该致电gethostbyaddr
或gethostbyname
,他们会返回指向hostent
的指针。这在MSDN中得到了很好的解释。如果您想手动设置hostent
,我不建议,您必须创建一个指向addr.s_addr
的指针数组,并将h_addr_list
设置为数组。该数组应包含最后一个null
元素。我没有看到任何你想要手动操作的原因,因为操作系统会为你做这件事。