4

recvfrom要求第 5 个参数是指向sockaddr结构的指针,第 6 个参数是指向 a 的指针socklen_t

man recvfrom (3)说:

如果地址的实际长度大于提供的 sockaddr 结构的长度,则应截断存储的地址。

我不明白如何使用 AF_INET6 地址系列检索发送套接字的地址,因为 的大小sockaddr_in6大于sockaddr它会被截断recvfrom

我是否正确recvfrom地无法检索大于的地址sizeof(sockaddr)

我是否理解正确,即使我定义了sockaddr_in6cast 的实例并将其sockaddr*传递给recvfrom,该函数也无法知道有足够的空间来存储地址?

4

2 回答 2

8

将其转换为 . 是正确的sockaddr*

此外,人们经常使用sockaddr_storage,因为它被定义

标头应定义 sockaddr_storage 结构。该结构应为:

  • 大到足以容纳所有受支持的特定于协议的地址结构
  • 在适当的边界对齐,以便可以将指向它的指针转换为指向协议特定地址结构的指针,并用于访问这些结构的字段而不会出现对齐问题

通过这种方式,您可以将它用于多种协议,因此您不仅限于 IPv6 或 IPv4。

所以你可以做

struct sockaddr_storage addr;
socklen_t sa_len = sizeof(addr);

recvfrom (sock, buffer, sizeof (buffer), (struct sockaddr*) &addr, &sa_len);

如果您需要知道 sockaddr 的 kinf 是什么,您可以检查sa_family_t ss_family每个 sockaddr 结构中存在的必填字段。

可能也对此链接或此链接感兴趣。

于 2013-08-19T06:52:55.467 回答
7

您将sockaddr_in6(类型转换)的指针和sockaddr_in6结构的大小作为参数传递:

struct sockaddr_in6 in6;
socklen_t len6 = sizeof(in6);

recvfrom(sock, buf, buflen, (struct sockaddr *) &in6, &len6);

由于您将正确的长度传递给函数,因此它将起作用。

于 2013-08-19T06:49:52.377 回答