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

标签 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

最佳答案

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

这些结构包含二进制 IP 地址、端口号(对于 TCP 或 UDP 等传输协议(protocol))、系列(也在 struct addrinfo 中重复)和其他数据(用于 TCP 或 UDP 的 flowinfo 和scope_id) IPv6,查看 Linux 文档时)。

实际的二进制地址位于struct sockaddr_instrict sockaddr_in6内部,分别为struct 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 进行算术运算,这不是一个好主意,因为类型可能会因操作系统而异,而且无论如何都没有逻辑。如果您有特定的用例或特定的代码,我可以添加更多详细信息。

关于c - 如何获取 getaddrinfo() 返回的 ai_addr->sa_data 的实际大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25959188/

相关文章:

c++ - WSAGetLastError() 返回 122

python - 重新连接期间的 getaddrinfo 行为

c - TAILQ_INSERT_TAIL 宏 <sys/queue.h>

c - 如何在 OSX 和 Linux 中处理 dlsym() 的不同行为(通用)

c - 冒泡排序——输出整数的字符串

c - 为什么 strtok 不起作用?

c - 运行一个简单的 libpcap 示例时出错

java - OSI层与Java之间的关系

linux - "zero copy networking"与 "kernel bypass"?

c - getaddrinfo 不适用于网络地址