sockaddr 和 sockaddr_in 的区别与联系

两个结构体如下所示

struct sockaddr {
        ushort sa_family;
        char    sa_data[14];
};

struct sockaddr_in {
        short   sin_family;   //地址族 Socket只能用AF_INET
        u_short sin_port;   //端口
        struct in_addr sin_addr; //IPv4网络地址
        char    sin_zero[8];   //
};


 

sockaddr 保留了未定义的区域,sockaddr_in 则定义了具体的成员
一般用sockaddr_in进行地址的装入
大部分用到地址结构的函数则用sockaddr结构体,这是为了扩展性。
这样,函数就不用跟具体的地址结构耦合了.
不过毕竟是C,将sockaddr_in传给接收sockaddr的函数时,
就要做强制类型转换,这种转换成功的前提是,
结构体必须保持上一层结构体已定义成员的顺序,
sockaddr第一个成员是sa_family,所以sockaddr_in的第一个成员也一定是sa_family
还有,更进一步,定义新的sockaddr时,增加成员的总空间还可以超过char[14],
就是可以无限扩展的意思.
函数一样可以正常工作,这就是为什么一般函数当需要一个sockaddr地址结构时,还要求传入一个sockaddr的大小

示例:
struct sockaddr_in saServer;
bind( ListenSocket,(SOCKADDR*) &saServer, sizeof(saServer) );

将一个saServer传入时,强制转换成SOCKADDR* , 接着还要传入saServer的大小
即sockaddr_in的大小,而不是sockaddr的大小

sa_family定义了地址族,不同的地址族地址结构是不同的
所以sa_family成为一种地址类型标识
sockaddr_in地址的domain是AF_INET
可以猜想,所有接收sockaddr结构体的函数,
都先通过sa_family判断地址族从而确定地址结构体的实际类型
这就是C语言中的多态!

你可能感兴趣的:(工作,struct,socket,domain,扩展,语言)