struct addrinfo和struct sockaddr有什么区别

时间:2014-05-01 02:22:22

标签: c sockets networking

据我所知,struct addrinfo用于准备套接字地址结构,struct sockaddr包含套接字地址信息。但这究竟意味着什么呢? struct addrinfo包含指向struct sockaddr的指针。为什么要将它们分开?为什么我们不能将sockaddr中的所有内容组合到addr_info中?

我只是在这里猜测,但他们分离的原因是为了在传递结构时节省空间?例如,在bind()调用中,它需要的只是端口号和Internet地址。所以这两个都分组在struct sockaddr中。那么,我们可以传递这个小结构而不是更大的结构addrinfo?

struct addrinfo {
    int              ai_flags;     // AI_PASSIVE, AI_CANONNAME, etc.
    int              ai_family;    // AF_INET, AF_INET6, AF_UNSPEC
    int              ai_socktype;  // SOCK_STREAM, SOCK_DGRAM
    int              ai_protocol;  // use 0 for "any"
    size_t           ai_addrlen;   // size of ai_addr in bytes
    struct sockaddr *ai_addr;      // struct sockaddr_in or _in6
    char            *ai_canonname; // full canonical hostname

    struct addrinfo *ai_next;      // linked list, next node
};

struct sockaddr {
    unsigned short    sa_family;    // address family, AF_xxx
    char              sa_data[14];  // 14 bytes of protocol address
}; 

1 个答案:

答案 0 :(得分:17)

struct addrinfo返回

getaddrinfo(),并且在成功时包含指定主机名和/或服务的struct的链接列表。

ai_addr成员实际上并不是struct sockaddr,因为struct仅仅是包含所有其他成员的通用成员的通用成员,并且用于确定你实际拥有的结构类型。根据您传递给getaddrinfo()的内容以及该功能发现的内容,ai_addr实际上可能是指向struct sockaddr_instruct sockaddr_in6或其他任何内容的指针,具体取决于具体内容适用于该特定地址条目。这是他们保持"分开"的一个很好的理由,因为该成员可能指向一堆不同类型的struct中的一个,它无法做到如果您尝试将所有成员硬编码到struct addrinfo,因为那些不同的struct具有不同的成员。

如果您有主机名,这可能是获取此信息的最简单方法,但这不是唯一的方法。对于IPv4连接,您可以自己填充struct sockaddr_in结构,如果您愿意并且您有数据可以这样做,并且避免经历调用getaddrinfo()的严格要求,您可能需要这样做等待它是否需要进入互联网为您收集信息。您根本不必使用struct addrinfo