我对linux网络地址的理解(struct sockaddr、struct sockaddr_in、struct sockaddr_in6)

1、我的理解

      在linux下写了多年的网络应用编程,一直copy&paste,今天突然发现对struct sockaddr、struct sockaddr_in、 struct in_addr这3个结构之间的关系还是模糊的,对什么时候该用哪个结构不清楚,惭愧啊。在此,翻阅了/usr/include下的头文件和阅读了一遍man手册,记录下来,权当对自己技术能力的反思。

1、struct sockaddr 结构:

typedef unsigned short int sa_family_t;

#define __SOCKADDR_COMMON(sa_prefix) \
  sa_family_t sa_prefix##family

struct sockaddr
{
    __SOCKADDR_COMMON (sa_);    /* Common data: address family and length.  */
    char sa_data[14];       /* Address data.  */
};

       它定义在sys/socket.h头文件中,定义它的目的是:因为bind、accept等API的实现屏蔽掉具体的网络协议族,所以就需要定义出1个通用的结构作为API的参数。所以用户在使用不同的协议族时,需要将具体的协议族地址结构的指针转换成struct sockaddr结构指针(如示例)。但无论使用什么协议族,具体协议族地址结构的第一个字段必须是sa_family_t类型,表示本地址具体使用的协议族(参见struct sockaddr_in、struct sockaddr_in6结构)。

struct sockaddr_in ipv4_addr;
struct sockaddr *addr = (struct sockaddr*)&addr;
bind(sockfd, addr, sizeof(ipv4_addr));

2、struct sockaddr_in 结构:

typedef uint16_t in_port_t;
typedef uint32_t in_addr_t;
struct in_addr { in_addr_t s_addr; };

struct sockaddr_in {
    sa_family_t sin_family;
    in_port_t sin_port;
    struct in_addr sin_addr;
    uint8_t sin_zero[8];
};

      它定义在netinet/in.h头文件中,它表示1个ipv4的地址,sizeof(struct sockaddr)与sizeof(struct sockaddr_in)刚好相等。

3、struct sockaddr_in6 结构:

struct in6_addr {
    union {
       uint8_t __s6_addr[16];
       uint16_t __s6_addr16[8];
       uint32_t __s6_addr32[4];
    } __in6_union;
};
#define s6_addr __in6_union.__s6_addr
#define s6_addr16 __in6_union.__s6_addr16
#define s6_addr32 __in6_union.__s6_addr32

struct sockaddr_in6 {
    sa_family_t     sin6_family;
    in_port_t       sin6_port;
    uint32_t        sin6_flowinfo;
    struct in6_addr sin6_addr;
    uint32_t        sin6_scope_id;
};

      它定义在netinet/in.h头文件中,它表示1个ipv6的地址,虽然sizeof(struct sockaddr)小于sizeof(sockaddr_in6);一般不会使用struct sockaddr结构定义的变量,只会使用struct sockaddr结构定义的指针;所以只会涉及指针类型的强转。切记不可以将struct sockaddr_in6的变量直接赋值给struct sockaddr的变量;当然一般也不会定义struct sockaddr的变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值