IPv6 套接字上的 recvfrom() 是否总是 return 'from' 参数中的 IPv6 地址?

Does recvfrom() on an IPv6 socket always return an IPv6 address in 'from' parameter?

IPv6 套接字上的 recvfrom() 是否总是 return from 参数中的 IPv6 地址?我担心的是,如果 IPv6 套接字通过 IPv4 映射的 IPv6 地址与 IPv4 目标通信,是否有可能 recvfrom() return 直接是 IPv4 地址?

AF_INET (IPv4) 套接字仅适用于 IPv4 地址。

AF_INET6 (IPv6) 套接字仅适用于 IPv6 地址。

A dual-stack socket 是一个 AF_INET6 套接字,关闭了 IPV6_V6ONLY 选项,因此它可以与 IPv4 和 IPv6 对等点一起工作。由于它是 IPv6 套接字,因此 IPv4 地址将始终表示为 IPv4 映射的 IPv6 地址。这在文档中有明确说明:

IP Addresses with a Dual-Stack Socket

Dual-stack sockets always require IPv6 addresses. The ability to interact with an IPv4 address requires the use of the IPv4-mapped IPv6 address format. Any IPv4 addresses must be represented in the IPv4-mapped IPv6 address format which enables an IPv6 only application to communicate with an IPv4 node. The IPv4-mapped IPv6 address format allows the IPv4 address of an IPv4 node to be represented as an IPv6 address. The IPv4 address is encoded into the low-order 32 bits of the IPv6 address, and the high-order 96 bits hold the fixed prefix 0:0:0:0:0:FFFF. The IPv4-mapped IPv6 address format is specified in RFC 4291. For more information, see www.ietf.org/rfc/rfc4291.txt. The IN6ADDR_SETV4MAPPED macro in Mstcpip.h can be used to convert an IPv4 address to the required IPv4-mapped IPv6 address format.

If the underlying protocol is actually IPv4, then the IPv4 address is mapped into an IPv4-mapped IPv6 address format. That is the, family field in the SOCKADDR structure indicates AF_INET6, but an IPv4-mapped IPv6 address is encoded in the IPv6 address structure. For a dual-stack socket in listening mode, this means that any accepted IPv4 connections will return an IPv4-mapped IPv6 address. For a dual-stack socket that is connecting to an IPv4 destination, the SOCKADDR structure passed to connect must be an IPv4-mapped IPv6 address. Applications must take care to handle these IPv4-mapped IPv6 addresses appropriately and only use them with dual stack sockets. If an IP address is to be passed to a regular IPv4 socket, the address must be a regular IPv4 address not a IPv4-mapped IPv6 address.