c - 在 connect() 中应该使用哪个 addrinfo 结构?

标签 c sockets getaddrinfo

我正在编写一个程序,可以连接到不同的网站并请求和下载网页。我这样做在很大程度上是为了学习和正确理解网络编程。我想知道 getaddrinfo 返回的指向类型为 struct addrinfo 的链表的指针是否按任何特定顺序排列,如果是这样,则选择连接的 ip 地址以任何方式都很重要。

例如,如果我运行 getaddrinfo("google.com", "http", &hints, &res)res 有时会有多达七个互联网地址。如果我连接到第一个或最后一个,这会有什么不同吗?请注意,我已经研究了此功能的手册页,据我所知,我的问题在那里没有得到解答。

最佳答案

由于您在链表中组织了多个 addrinfo 结构,您应该对其进行迭代并尝试连接,直到连接成功.即:

struct addrinfo *ptr = res;

while (res != NULL) {
     int rc = connect(socket_fd, (sockaddr *) ptr->ai_addr, ptr->addr_len);
     if (rc == 0) 
         break; // we managed to connect successfully
     // handle error

这可能是需要的,因为 DNS 查找可以返回多个条目,因此需要有一个链表才能允许您访问它们。 如果 connect 成功,你就完成了;如果失败,您应该继续尝试查找返回的每个可用 IP,从而将指针推进到下一个元素。此外,考虑到 connect 可能因多种原因而失败,因此您需要检查 errno 以查找可能允许进一步尝试的错误。正如@R.. 指出的那样,您还必须通过 connect 一个新的套接字,因为地址族可能会更改,从而释放前一个套接字; getaddrinfo 将为您提供帮助,因为此信息在 addrinfo 节点 (ai_family) 中提供。

但是,这通常不必要:第一个结果通常会起作用。就我个人而言,如果可以的话,我从未遇到过循环访问链表的需要,但了解它仍然很好,以备不时之需。

getaddrinfo(3)

There are several reasons why the linked list may have more than one addrinfo structure, including: the network host is multihomed, accessible over multiple protocols (e.g., both AF_INET and AF_INET6); or the same service is available from multiple socket types (one SOCK_STREAM address and another SOCK_DGRAM address, for example). Normally, the application should try using the addresses in the order in which they are returned. The sorting function used within getaddrinfo() is defined in RFC 3484; the order can be tweaked for a particular system by editing /etc/gai.conf (available since glibc 2.5).

关于c - 在 connect() 中应该使用哪个 addrinfo 结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28384146/

相关文章:

java - java.net.Socket 线程安全的方式是什么?

c - 具有 `addrinfo` 结构的内存管理

python-3.x - 无法为python 3 recv设置超时

Python 套接字 - 让套接字保持事件状态?

Node.js http.request 失败并显示 [错误 : getaddrinfo EADDRINFO]

linux - Linux平台上getaddrinfo()函数调用的问题

c - MK时间 : unexpected result

c - 当套接字无效时

C编程,如何在多个字段类型中使用定界符%

c - 全局变量不能正常工作C