структура sockaddr_un против sockaddr
Чем struct sockaddr
отличается от struct sockaddr_un
?
Я знаю, что мы используем эти структуры в клиент-серверных модулях для привязки сокета к адресу сокета. И мы используем оператор приведения, чтобы он принимал struct sockaddr_un
.
Я хочу знать, насколько они различны/похожи, и почему оператор приведения?
Ответы
Ответ 1
"struct sockaddr" является общим определением. Он используется любой функцией сокета, для которой требуется адрес.
"struct sockaddr_un" (адрес "Unix sockets" ) - это определенный тип семейства адресов.
Наиболее часто встречающийся "struct sockaddr_in" (адрес "Интернет-сокета" ) - это еще один тип семейства адресов.
Листинг - это то, что позволяет API-интерфейсам сокетов принимать общий тип параметра, который фактически будет любым из нескольких разных фактических типов.
Здесь хорошая ссылка, которая показывает несколько различных определений семейств адресов:
http://www.cas.mcmaster.ca/~qiao/courses/cs3mh3/tutorials/socket.html
Ответ 2
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 */
}
/* ... */