A struct sockaddr
обычно следует использовать только в качестве базового типа для указателя.Это структура, предназначенная для охвата общей начальной последовательности элементов в типах адресов сокетов, специфичных для семейства адресов (struct sockaddr_un
, struct sockaddr_in
, struct sockaddr_in6
и т.на struct sockaddr
имеется один sa_family_t
, указывающий семейство адресов сокетов.Идея состоит в том, чтобы получить своего рода полиморфизм - у вас может быть функция, которая может работать с несколькими различными типами адресов сокетов:
void foo(struct sockaddr *sa)
{
switch(sa->sa_family)
{
case AF_INET: {
struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
/* AF_INET processing */
}
case AF_UNIX: {
struct sockaddr_un *sa_un = (struct sockaddr_un *)sa;
/* AF_UNIX processing */
}
/* ... */
Обратите внимание, что такой код, как указано выше, обычно считается нарушающимпсевдоним "правило в C - если вы хотите сделать это в своем собственном коде, вы должны использовать тип объединения:
union sockaddr {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_un sun;
/* ... */
};
void foo(union sockaddr *sa_union)
{
struct sockaddr *sa = (struct sockaddr *)sa_union;
switch(sa->sa_family)
{
case AF_INET: {
struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
/* AF_INET processing */
}
case AF_UNIX: {
struct sockaddr_un *sa_un = (struct sockaddr_un *)sa;
/* AF_UNIX processing */
}
/* ... */