据我所知,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
};
答案 0 :(得分:17)
struct addrinfo
返回 getaddrinfo()
,并且在成功时包含指定主机名和/或服务的struct
的链接列表。
ai_addr
成员实际上并不是struct sockaddr
,因为struct
仅仅是包含所有其他成员的通用成员的通用成员,并且用于确定你实际拥有的结构类型。根据您传递给getaddrinfo()
的内容以及该功能发现的内容,ai_addr
实际上可能是指向struct sockaddr_in
或struct sockaddr_in6
或其他任何内容的指针,具体取决于具体内容适用于该特定地址条目。这是他们保持"分开"的一个很好的理由,因为该成员可能指向一堆不同类型的struct
中的一个,它无法做到如果您尝试将所有成员硬编码到struct addrinfo
,因为那些不同的struct
具有不同的成员。
如果您有主机名,这可能是获取此信息的最简单方法,但这不是唯一的方法。对于IPv4连接,您可以自己填充struct sockaddr_in
结构,如果您愿意并且您有数据可以这样做,并且避免经历调用getaddrinfo()
的严格要求,您可能需要这样做等待它是否需要进入互联网为您收集信息。您根本不必使用struct addrinfo
。