C语言 struct addrinfo 和 struct sockaddr 有什么区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23401147/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:03:30  来源:igfitidea点击:

What is the difference between struct addrinfo and struct sockaddr

csocketsnetworking

提问by

From what I understand struct addrinfo is used to prep the socket address structure and struct sockaddr contains socket address information. But what does that actually mean? struct addrinfo contains a pointer to a struct sockaddr. Why keep them separate? Why can't we combine all things within sockaddr into addr_info?

据我了解,struct addrinfo 用于准备套接字地址结构,struct sockaddr 包含套接字地址信息。但这实际上意味着什么?struct addrinfo 包含一个指向 struct sockaddr 的指针。为什么要把它们分开?为什么我们不能将 sockaddr 中的所有东西都合并到 addr_info 中?

I'm just guessing here but is the reason for their separation is to save space when passing structs? For example in the bind() call, all it needs is the port number and the internet address. So both of these are grouped in a struct sockaddr. So, we can just pass this small struct instead of the larger struct addrinfo?

我只是在这里猜测,但它们分离的原因是为了在传递结构时节省空间吗?例如在 bind() 调用中,它所需要的只是端口号和互联网地址。所以这两个都被分组在一个 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
}; 

采纳答案by Crowman

struct addrinfois returned by getaddrinfo(), and contains, on success, a linked list of such structs for a specified hostname and/or service.

struct addrinfo由 返回getaddrinfo(),并在成功时包含struct指定主机名和/或服务的此类s的链接列表。

The ai_addrmember isn't actually a struct sockaddr, because that structis merely a generic one that contains common members for all the others, and is used in order to determine what type of struct you actually have. Depending upon what you pass to getaddrinfo(), and what that function found out, ai_addrmight actually be a pointer to struct sockaddr_in, or struct sockaddr_in6, or whatever else, depending upon what is appropriate for that particular address entry. This is one good reason why they're kept "separate", because that member might point to one of a bunch of different types of structs, which it couldn't do if you tried to hardcode all the members into struct addrinfo, because those different structs have different members.

ai_addr成员实际上不是 a struct sockaddr,因为那struct只是一个包含所有其他成员的通用成员的通用成员,用于确定您实际拥有的结构类型。根据您传递给 的内容getaddrinfo()以及该函数发现的内容,ai_addr实际上可能是指向struct sockaddr_in、 或struct sockaddr_in6或其他任何内容的指针,具体取决于适合该特定地址条目的内容。这是它们保持“分离”的一个很好的原因,因为该成员可能指向一堆不同类型的structs 中的一个,如果您尝试将所有成员硬编码到 中struct addrinfo,则无法做到这一点,因为那些不同的structs有不同的成员。

This is probably the easiest way to get this information if you have a hostname, but it's not the only way. For an IPv4 connection, you can just populate a struct sockaddr_instructure yourself, if you want to and you have the data to do so, and avoid going through the rigamarole of calling getaddrinfo(), which you might have to wait for if it needs to go out into the internet to collect the information for you. You don't have to use struct addrinfoat all.

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