解释 getaddrinfo( ) 的参数

Posted

技术标签:

【中文标题】解释 getaddrinfo( ) 的参数【英文标题】:Explain parameters of getaddrinfo( ) 【发布时间】:2015-10-01 19:31:56 【问题描述】:

我不明白的是**res 双指针,在手册页中它指出:

hints 参数指向一个 addrinfo 结构,该结构指定 选择返回的套接字地址结构的标准 res 指向的列表。

我看到*hints 是一个指向addrinfo 结构的指针,但是**res 如何返回套接字地址结构?

Specification:

int getaddrinfo(const char *node, const char *service,
                const struct addrinfo *hints,
                struct addrinfo **res);


struct addrinfo 
    int              ai_flags;
    int              ai_family;
    int              ai_socktype;
    int              ai_protocol;
    socklen_t        ai_addrlen;
    struct sockaddr *ai_addr;
    char            *ai_canonname;
    struct addrinfo *ai_next;
;

【问题讨论】:

看看文档,在页面的最末尾man7.org/linux/man-pages/man3/getaddrinfo.3.html - 敢于克服 TL;DR 【参考方案1】:

使用指向指针的指针是一种常见模式,其中函数使用“out”参数返回已分配内存的地址。这样做是为了让调用者不必预先分配,有时是未知的大小。

典型的用法是通过地址操作符 (&) 使用指针类型,如下所示:

struct addrinfo *result;
getaddrinfo("foo", "baz", NULL, &result);

然后,result,这是一个未初始化的变量正在指向一个真实的内存地址,稍后在代码中预计它将被调用者释放:

freeaddrinfo(result);

【讨论】:

C 没有引用,并且一元 & 运算符在 C 上下文中通常不称为“引用”运算符。事实上,即使在 C++ 中,我也不认为使用 & 来标记引用类型符合操作的条件。该标准将一元 & 称为“地址”运算符,在其他地方我经常看到拼写为“地址”。但是,否则,您的解释很好。 @JohnBollinger A. 你是对的。 B. 我什至没有注意到它是 C 而不是 C++ :-) 我在下面发布的相同评论,为什么它使用** double 而不是* single,addrinfo 结构不是指针,所以他们为什么在规范中使用 double。 @JordanDavis 该变量被定义为一个指针(1 *),因此它指向一个带有结构值的内存地址。地址运算符获取变量的地址并将其传递给函数,以便它 (getaddrinfo) 可以“改变”变量,并设置它指向的地址。这很像你有一个函数:void f(int *i) ;,你把它和int i; f(&i);一起使用。 我明白了……再说一遍,为什么它使用** 而不是* single【参考方案2】:

res 是一个指针,指向您希望存储结果(本身是指针形式)的位置。因此,您可以执行以下操作:

struct addrinfo hints =  .ai_socktype = SOCK_STREAM ;
struct addrinfo *ai;
int err_code = getaddrinfo(hostname, service, &hints, &ai));

之后,如果没有错误,ai 已更新为指向您的结果(addrinfo 结构的链表的第一个元素)。

【讨论】:

为什么** double,即使在您的示例中,您使用* 单,甚至在“客户端程序”man7.org/linux/man-pages/man3/getaddrinfo.3.html 下的手册页中,它也使用struct addrinfo *result, *rp;,这是单。我的意思是 struct addrinfo 不是指针,所以我为什么要声明 ** 双精度,你知道的。 @JordanDavis:res 参数是指向存储结果的位置的指针。结果本身具有指针类型。因此,参数是指向指针的指针。这并不意味着结果对象(在我的示例代码中为ai)应该是双指针类型。相反,您传递它的地址&ai,其类型是“指向ai 类型的指针”,因此指向指向struct addrinfo 的指针

以上是关于解释 getaddrinfo( ) 的参数的主要内容,如果未能解决你的问题,请参考以下文章

getaddrinfo with fist NULL参数给出第一个IPv4而不是IPv6

getaddrinfo() 无法解析winsock

VC++6.0中getaddrinfo()方法

python 实现dns请求,dns_request(socket getaddrinfo whiel)

浅谈getaddrinfo函数的超时处理机制

带有 systemd 的 getaddrinfo() API