¿Cuál es la diferencia entre sockaddr, sockaddr_in y sockaddr_in6?

Sé que sockaddr_in es para IPv4, y sockaddr_in6 para IPv6. La confusión para mí es la diferencia entre sockaddr y sockaddr_in [6].

Algunas funciones aceptansockaddr y algunas funciones aceptansockaddr_in osockaddr_in6, asi que:

¿cual es la regla?¿Y por qué hay necesidad de dos estructuras diferentes?

Y porque elsizeof(sockaddr_in6) > sizeof(sockaddr) == sizeof(sockaddr_in).

¿Eso significa que siempre deberíamos usar sockaddr_in6 para asignar memoria en la pila y convertir a sockaddr y sockaddr_in si necesitamos admitir ipv4 y ipv6?

Un ejemplo es: tenemos un socket y queremos obtener la dirección IP de la cadena (puede ser ipv4 o ipv6).

Primero llamamosgetsockname para obtener unaddr y luego llamarinet_ntop basado en eladdr.sa_family.

¿Hay algo malo con este fragmento de código?

sockaddr_in6 addr_inv6;
sockaddr* addr = (sockaddr*)&addr_inv6;
sockaddr_in* addr_in = (sockaddr_in*)&addr_inv6;

socklen_t len = sizeof(addr_inv6);
getsockname(_socket, addr, &len);
char ipStr[256];
if (addr->sa_family == AF_INET6)
{
    inet_ntop(addr_inv6.sin6_family, &addr_inv6.sin6_addr, ipStr, sizeof(ipStr)); 
    // <<<<<<<<IS THIS LINE VALID, getsockname expected a sockaddr, but we use it output parameter as sockaddr_in6.
}
else
{
    inet_ntop(addr_in->sin_family, &addr_in->sin_addr, ipStr, sizeof(ipStr));
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta