【问题标题】:Why does getaddrinfo() return a value in the inputs part of the function?为什么 getaddrinfo() 在函数的输入部分返回一个值?
【发布时间】:2017-09-17 17:22:20
【问题描述】:

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);

根据 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”不是一个通过迭代来获取地址的数组?为什么输入也返回结果?

【问题讨论】:

  • 如果你仔细看,rv确实用在了第二行。当它被传递给gai_seterror 以格式化错误消息给用户以指示调用失败的原因。
  • 做一些关于在C中模拟通过引用传递的研究。
  • 您不能引用第三方网站作为参考。您是否考虑过查阅 man 页面?

标签: c sockets networking getaddrinfo


【解决方案1】:

使用了值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() 的结果,但这有点笨拙。

【讨论】:

    【解决方案2】:

    函数的编码方式是返回值只是一个状态码——无论函数执行成功与否。然后将更复杂的结果集填充到提供的链表指针中。

    在 C 中做这样的事情并不少见。**res 表示法肯定会令人困惑,但这相当于说在 java 中给函数一个空的 LinkedList 对象,然后函数会填充该对象。

    总而言之——在 C 语言中——这并不少见。当输入通过引用/指针而不是值传递时,获取它们的函数可以对它们做任何事情。在其他语言中也是如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多