struct sockaddr
与struct sockaddr_un
的区别如何?
我知道我们在客户端 - 服务器模块中使用这些结构,用于将套接字绑定到套接字地址。我们使用强制转换运算符来接受结构sockaddr_un
。
我想知道它们有多么不同/类似,为什么是演员?
答案 0 :(得分:28)
“struct sockaddr”是一个通用定义。任何需要地址的套接字函数都会使用它。
“struct sockaddr_un”(“Unix套接字”地址)是一种特定的地址族。
更常见的“struct sockaddr_in”(“Internet套接字”地址)是另一种特定类型的地址族。
强制转换允许套接字API接受一个通用参数类型,它实际上是几种不同实际类型中的任何一种。
这是一个很好的链接,显示了几个不同的地址族定义:
http://www.cas.mcmaster.ca/~qiao/courses/cs3mh3/tutorials/socket.html
答案 1 :(得分:23)
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 */
}
/* ... */