简体   繁体   English

如何获取getaddrinfo()返回的ai_addr-> sa_data的实际大小

[英]How to get actual size of ai_addr->sa_data returned by getaddrinfo()

getaddrinfo() fills struct addrinfo where actual packed address stored in struct sockaddr *ai_addr field. getaddrinfo()填充struct addrinfo ,其中实际打包地址存储在struct sockaddr *ai_addr字段中。 struct sockaddr has field char *sa_data with actual binary address representation. struct sockaddr具有字段char *sa_data具有实际的二进制地址表示。 I want to copy this sa_data to another variable using memcpy() , for this I need to know actual length of this field. 我想使用memcpy()将此sa_data复制到另一个变量,为此我需要知道该字段的实际长度。

I thinked ai_addrlen is what I need. 我认为ai_addrlen是我需要的。 But in fact it returns 16 for IPv4 and 28 for IPv6. 但事实上,它为IPv4返回16,为IPv6返回28。 Too much I think. 我觉得太多了。 So, what is the most correct way to get sa_data length? 那么,获得sa_data长度的最正确方法是什么? May be length = sa_family == AF_INET ? 4 : 16 可能是length = sa_family == AF_INET ? 4 : 16 length = sa_family == AF_INET ? 4 : 16 or length = ai_addrlen - 12 ? length = sa_family == AF_INET ? 4 : 16length = ai_addrlen - 12

The getaddrinfo() function returns a linked list consisting of struct addrinfo records. getaddrinfo()函数返回一个由struct addrinfo记录组成的链表。 Each of those records includes a pointer to struct sockaddr which is a polymorphic type, behind which there is actually a struct sockaddr_in or struct sockaddr_in6 . 这些记录中的每一个都包含一个指向struct sockaddr的指针,这是一个多态类型,在其后面实际上有一个struct sockaddr_instruct sockaddr_in6 The ai_addrlen member tells you how large is that structure, ie returns either sizeof (struct sockaddr_in) or sizeof (struct sockaddr_in6) . ai_addrlen成员告诉您该结构有多大,即返回sizeof (struct sockaddr_in)sizeof (struct sockaddr_in6)

Those structures contain the binary IP address, the port number (for the transport protocol like TCP or UDP), the family (repeated in struct addrinfo as well) and other data (flowinfo and scope_id for IPv6, when looking at linux docs). 这些结构包含二进制IP地址,端口号(用于传输协议,如TCP或UDP),系列(在struct addrinfo重复)和其他数据(用于IPv6的flowinfo和scope_id,当查看linux文档时)。

The actual binary address is inside the struct sockaddr_in and strict sockaddr_in6 as struct in_addr sin_addr and struct in6_addr sin6_addr . 实际的二进制地址在struct sockaddr_instrict sockaddr_in6作为struct in_addr sin_addrstruct in6_addr sin6_addr You can use those fields or types to determine the size. 您可以使用这些字段或类型来确定大小。

length = sa_family == AF_INET ? sizeof (struct in_addr) : sizeof (struct in6_addr)

As those are known numbers, you can of course use what you have already in your question. 由于这些已知数字,您当然可以使用您在问题中已有的数字。

length = sa_family == AF_INET ? 4 : 16

But you also tried to do arithmetics on ai_addrlen and that is not a good idea, as the types can vary by operating system and there's no logic in that anyway. 但是你也尝试在ai_addrlen上做算术,这不是一个好主意,因为类型可能因操作系统而异,但无论如何都没有逻辑。 I can add more details if you had a specific use case or specific code. 如果您有特定的用例或特定代码,我可以添加更多详细信息。

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

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