菜鸟笔记
提升您的技术认知

sockaddr与sockaddr-ag真人游戏

在demo中,bind() 第二个参数的类型为 sockaddr,而代码中却使用 sockaddr_in,然后再强制转换为 sockaddr,这是为什么呢?

两者结构体对比

括号内为所占用的字节数:

sockaddr结构体

struct sockaddr{
  
    sa_family_t  sin_family;   //地址族(address family),也就是地址类型
    char         sa_data[14];  //ip地址和端口号
};

sockaddr_in 结构体

struct sockaddr_in{
  
    sa_family_t     sin_family;   //地址族(address family),也就是地址类型
    uint16_t        sin_port;     //16位的端口号
    struct in_addr  sin_addr;     //32位ip地址
    char            sin_zero[8];  //不使用,一般用0填充
};

sockaddrsockaddr_in的长度相同,都是16字节,只是将ip地址和端口号合并到一起,用一个成员 sa_data表示。要想给 sa_data赋值,必须同时指明ip地址和端口号,例如"127.0.0.1:80",遗憾的是,没有相关函数将这个字符串转换成需要的形式,也就很难给 sockaddr类型的变量赋值,所以使用 sockaddr_in 来代替。这两个结构体的长度相同,强制转换类型时不会丢失字节,也没有多余的字节。

可以认为,sockaddr 是一种通用的结构体,可以用来保存多种类型的ip地址和端口号,而 sockaddr_in 是专门用来保存 ipv4 地址的结构体。另外还有 sockaddr_in6,用来保存 ipv6 地址,它的定义如下:

struct sockaddr_in6 {
  
sa_family_t sin6_family;  //(2)地址类型,取值为af_inet6
in_port_t sin6_port;  //(2)16位端口号
uint32_t sin6_flowinfo;  //(4)ipv6流信息
struct in6_addr sin6_addr;  //(4)具体的ipv6地址
uint32_t sin6_scope_id;  //(4)接口范围id
};

正是由于通用结构体 sockaddr 使用不便,才针对不同的地址类型定义了不同的结构体。

网站地图