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 : 16
或length = ai_addrlen - 12
?
答案 0 :(得分:3)
getaddrinfo()
函数返回由struct addrinfo
条记录组成的链表。这些记录中的每一个都包含指向struct sockaddr
的指针,该指针是多态类型,其后实际上有struct sockaddr_in
或struct sockaddr_in6
。 ai_addrlen
成员会告诉您该结构的大小,即返回sizeof (struct sockaddr_in)
或sizeof (struct sockaddr_in6)
。
这些结构包含二进制IP地址,端口号(用于传输协议,如TCP或UDP),系列(在struct addrinfo
中重复)和其他数据(用于IPv6的flowinfo和scope_id,当查找时)在linux docs)。
实际二进制地址位于struct sockaddr_in
和strict sockaddr_in6
内struct in_addr sin_addr
和struct 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
上做算术,这不是一个好主意,因为类型可能会因操作系统而有所不同,无论如何都没有逻辑。如果您有特定的用例或特定代码,我可以添加更多详细信息。