getaddrinfo()的定义是:
int getaddrinfo(const char *node, // e.g. "www.example.com" or IP
const char *service, // e.g. "http" or port number
const struct addrinfo *hints,
struct addrinfo **res);
Per Beej的site它说:
"你给这个函数三个输入参数,它给你一个指向结果的链表res的指针。"
就使用而言:
if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("server: socket");
continue;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("server: bind");
continue;
}
break;
}
实际回报值" rv"实际上从未使用过。但结果来自第四个输入" res"或者" servinfo"在这个例子中。我理解链接列表涉及但我不清楚为什么函数返回不以正常方式起作用。为什么不是" rv"一个迭代的数组来获取地址?为什么输入也返回结果?
答案 0 :(得分:2)
使用了值rv
。如果操作成功则包含0,如果失败则包含错误代码。您甚至可以在问题中提供的示例代码中看到rv
!
// ↓ result is compared to 0
if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
// ↑ error message based on rv
return 1;
}
C不支持具有多个返回值的函数。在具有多个输出的getaddrinfo()
函数中,至少有一个输出必须作为指针传递给函数。
或者,可以定义一个结构来包含getaddrinfo()
的结果,但这有点笨拙。
答案 1 :(得分:1)
函数编码的方式是返回值只是一个状态代码 - 函数是否成功执行。然后将更复杂的结果集填充到提供的链表指针中。
在C语言中做这样的事情并不是一种罕见的做法。** res符号当然令人困惑,但它等同于在java中为函数提供一个空的LinkedList对象,然后该函数会填充。
总结 - 在C中 - 这并不罕见。当输入通过引用/指针而不是值传递时,获取它们的函数可以用它们做它想要的。在其他语言中也是如此。