简体   繁体   English

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

[英]Which addrinfo struct should be used in connect()?

I am writing a program that would connect to different websites and request and download web-pages. 我正在编写一个程序,可以连接到不同的网站,请求和下载网页。 I am doing this in large part to learn and properly understand web programming. 我这样做很大程度上是为了学习和正确理解网络编程。 I would like to know if the pointer to a linked list of type struct addrinfo returned by getaddrinfo is arranged in any particular order , and if so does the ip address chosen to connect to matter in any way. 我想知道getaddrinfo返回的类型struct addrinfo的链接列表的指针是否以任何特定顺序排列,如果是这样,选择以任何方式连接到物质的ip地址。

For example, if I run getaddrinfo("google.com", "http", &hints, &res) , res will sometimes have up to seven internet addresses. 例如,如果我运行getaddrinfo("google.com", "http", &hints, &res) ,则res有时最多会有七个互联网地址。 Does it make a difference in any way if I connect to the first one or the last one? 如果我连接到第一个或最后一个,它会以任何方式产生影响吗? Please note that I have studied the manual pages for this function and to my understanding, my question is not answered there. 请注意,我已经研究了这个功能的手册页,据我了解,我的问题没有在那里得到解答。

Since you have multiple addrinfo structures organized in a linked list, you should iterate over it and try to connect until a connection is successful. 由于您在链表中组织了多个addrinfo结构,因此您应该迭代它并尝试connect直到连接成功。 That is: 那是:

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

This might be needed because the DNS lookup can return multiple entries, thus the need to have a linked list in order to allow you to access them. 这可能是必需的,因为DNS查找可以返回多个条目,因此需要具有链接列表以允许您访问它们。 If connect succeeds, you're done; 如果connect成功,你就完成了; if it fails, you should keep trying for each available IP the lookup returned, so advancing the pointer to the next element. 如果失败,你应该继续尝试查找返回的每个可用IP,从而将指针推进到下一个元素。 Moreover, consider that connect can fail for multiple reasons therefore you need to check errno for errors that may allow further attempts. 此外,考虑到connect可能由于多种原因而失败,因此您需要检查errno是否存在可能允许进一步尝试的错误。 As @R.. pointed out, you also have to pass connect a new socket as the address family may change, releasing the previous one; 正如@R ..指出的那样,你也必须通过connect一个新的套接字,因为地址族可能会改变,释放前一个; getaddrinfo will help you since this information is provided in the addrinfo node ( ai_family ). getaddrinfo将帮助您,因为addrinfo节点( ai_family )中提供了此信息。

However, this is typically unnecessary : the first result will generally work. 但是,这通常是不必要的 :第一个结果通常会起作用。 Personally, if I may, I have never encountered the need to loop through the linked list but it's still good to know in case you might need that. 就个人而言,如果可以的话,我从来没有遇到过遍历链表的需要,但是如果你可能需要的话,它仍然是很好的。

getaddrinfo(3) 的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 (eg, both AF_INET and AF_INET6); 链表可能具有多个addrinfo结构的原因有多种,包括:网络主机是多宿主的,可通过多种协议访问(例如,AF_INET和AF_INET6); or the same service is available from multiple socket types (one SOCK_STREAM address and another SOCK_DGRAM address, for example). 或者多个套接字类型可以使用相同的服务(例如,一个SOCK_STREAM地址和另一个SOCK_DGRAM地址)。 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; getaddrinfo()中使用的排序函数在RFC 3484中定义; the order can be tweaked for a particular system by editing /etc/gai.conf (available since glibc 2.5). 通过编辑/etc/gai.conf(从glibc 2.5开始可用),可以为特定系统调整顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM