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

时间:2014-09-21 12:30:56

标签: c network-programming getaddrinfo

getaddrinfo()填充struct addrinfo,其中存储在struct sockaddr *ai_addr字段中的实际打包地址。 struct sockaddr具有字段char *sa_data,其中包含实际的二进制地址表示。我想使用memcpy()将此sa_data复制到另一个变量,为此我需要知道该字段的实际长度。

我认为ai_addrlen是我需要的。但事实上,它为IPv4返回16,为IPv6返回28。我觉得太多了。那么,获得sa_data长度的最正确方法是什么?可能是length = sa_family == AF_INET ? 4 : 16length = ai_addrlen - 12

1 个答案:

答案 0 :(得分:3)

getaddrinfo()函数返回由struct addrinfo条记录组成的链表。这些记录中的每一个都包含指向struct sockaddr的指针,该指针是多态类型,其后实际上有struct sockaddr_instruct sockaddr_in6ai_addrlen成员会告诉您该结构的大小,即返回sizeof (struct sockaddr_in)sizeof (struct sockaddr_in6)

这些结构包含二进制IP地址,端口号(用于传输协议,如TCP或UDP),系列(在struct addrinfo中重复)和其他数据(用于IPv6的flowinfo和scope_id,当查找时)在linux docs)。

实际二进制地址位于struct sockaddr_instrict sockaddr_in6struct in_addr sin_addrstruct in6_addr sin6_addr。您可以使用这些字段或类型来确定大小。

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

由于这些是已知数字,您当然可以使用您在问题中已有的数字。

length = sa_family == AF_INET ? 4 : 16

但是你也尝试在ai_addrlen上做算术,这不是一个好主意,因为类型可能会因操作系统而有所不同,无论如何都没有逻辑。如果您有特定的用例或特定代码,我可以添加更多详细信息。