结构sockaddr\u un与sockaddr

结构sockaddr\u un与sockaddr,c,linux,sockets,struct,client-server,C,Linux,Sockets,Struct,Client Server,struct sockaddr与struct sockaddr\u un有何不同 我知道我们在客户机-服务器模块中使用这些结构,用于将套接字绑定到套接字地址。我们使用cast操作符来接受structsockaddr\u un 我想知道它们有多不同/相似,以及为什么使用cast运算符?“struct sockaddr”是一个通用定义。任何需要地址的套接字函数都可以使用它 “struct sockaddr_un”(Unix套接字地址)是一种特定的地址族 更常见的“struct sockaddr_in

struct sockaddr
struct sockaddr\u un
有何不同

我知道我们在客户机-服务器模块中使用这些结构,用于将套接字绑定到套接字地址。我们使用cast操作符来接受struct
sockaddr\u un

我想知道它们有多不同/相似,以及为什么使用cast运算符?

“struct sockaddr”是一个通用定义。任何需要地址的套接字函数都可以使用它

“struct sockaddr_un”(Unix套接字地址)是一种特定的地址族

更常见的“struct sockaddr_in”(一个“Internet套接字”地址)是另一种特定的地址族

强制转换允许套接字API接受一个公共参数类型,该参数类型实际上是几种不同实际类型中的任意一种

这里有一个很好的链接,显示了几种不同的地址族定义:


A
struct sockaddr
通常只能用作指针的基类型。它是一种结构,旨在覆盖特定于地址系列的套接字地址类型中成员的公共初始序列(
struct sockaddr\u un
struct sockaddr\u in
struct sockaddr\u in 6
等)

唯一可以依赖的
struct sockaddr
成员是单个
sa_family\u 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 */
    }

/* ... */

提供的链接为unix和internet套接字中的差异提供了清晰的视图