sockaddr 和 sockaddr_in 的差别和联系

本文介绍了Sockfd的概念,它是socket函数返回的描述符。同时详细解释了sockaddr和sockaddr_in两种结构类型,包括它们的成员变量及其用途。sockaddr用于保存socket信息,而sockaddr_in则是更易于使用的版本。

Sockfd是调用socket函数返回的socket描述符,my_addr是个指向包含有本机IP地址及端口号等信息的sockaddr类型的指
针;addrlen常被设置为sizeof(struct sockaddr)。
   
struct sockaddr结构类型是用来保存socket信息的:
   
struct sockaddr
{   
unsigned short sa_family; /* 地址族, AF_xxx */
char sa_data[14]; /* 14 字节的协议地址 */
};
sa_family一般为AF_INET,代表Internet(TCP/IP)地址族;
sa_data则包含该socket的IP地址和端口号。

另外更有一种结构类型:   
struct sockaddr_in
{   
short int sin_family; /* 地址族 */
unsigned short int sin_port; /* 端口号 */   
struct in_addr sin_addr;/* IP地址 */   
unsigned char sin_zero[8]; /* 填充0 以保持和struct sockaddr同样大小*/   
};   
这个结构更方便使用。
sin_zero用来将sockaddr_in结构填充到和struct sockaddr同样的长度,能用bzero()或memset()函数将其置为零。指向sockaddr_in的指针和指向sockaddr的指针能相互转换,这意味着如果一个函数所需参数类型是sockaddr时,你能在函数调用的时候将一个指向sockaddr_in的指针转换为指向sockaddr的指针;或相反。

 

来源: ChinaUnix博客  作者: ChinaUnix博客

### `sockaddr_in` `sockaddr_storage` 的区别 `sockaddr_in` `sockaddr_storage` 是用于处理网络地址信息的结构体,它们在设计目的使用场景上存在显著差异。 `sockaddr_in` 是专门用于 IPv4 地址的结构体,其定义如下: ```c struct sockaddr_in { sa_family_t sin_family; /* 地址族,AF_INET */ in_port_t sin_port; /* 端口号,网络字节顺序 */ struct in_addr sin_addr; /* IPv4 地址 */ char sin_zero[8]; /* 填充字段,保留 */ }; ``` 该结构体的大小固定,适合用于 IPv4 地址的存储操作,但不支持 IPv6 地址 [^1]。 相比之下,`sockaddr_storage` 是一个通用的地址存储结构体,其设计目的是为了兼容 IPv4 IPv6 地址,同时提供足够的空间以容纳不同类型的地址信息。其定义如下: ```c struct sockaddr_storage { sa_family_t ss_family; /* 地址族 */ char __ss_padding[_SS_PADSIZE]; uint64_t __ss_align; /* 用于内存对齐的字段 */ }; ``` `sockaddr_storage` 的大小通常比 `sockaddr_in` 更大,以确保能够容纳最长的地址结构(如 IPv6 地址)。由于其通用性,`sockaddr_storage` 常用于需要同时处理 IPv4 IPv6 地址的场景,例如 `bind()`、`connect()` 等函数的参数传递 [^1]。 ### 使用场景的区别 `sockaddr_in` 适用于仅需要处理 IPv4 地址的场景。由于其结构简单且固定,它在 IPv4 网络编程中广泛使用。然而,当需要同时支持 IPv4 IPv6 地址时,`sockaddr_in` 的局限性就显现出来。 `sockaddr_storage` 适用于需要兼容 IPv4 IPv6 的场景。例如,在通用网络库中,为了支持多种地址类型,通常会使用 `sockaddr_storage` 作为地址存储的容器。通过检查 `ss_family` 字段,可以判断地址类型,并将其转换为对应的结构体(如 `sockaddr_in` 或 `sockaddr_in6`)进行进一步处理 [^1]。 ### 内存对齐转换 由于 `sockaddr_storage` 的定义中包含了用于内存对齐的字段(如 `__ss_align`),它能够确保在不同平台上地址结构的正确对齐,从而避免因内存对齐问题导致的访问错误。而 `sockaddr_in` 没有类似的对齐字段,因此在某些平台上可能需要手动对齐 [^1]。 在实际使用中,`sockaddr_storage` 可以通过强制类型转换为 `sockaddr_in` 或 `sockaddr_in6`,从而访问具体的地址信息。例如: ```c struct sockaddr_storage storage; struct sockaddr_in *addr_in = (struct sockaddr_in *)&storage; ``` 通过这种方式,可以动态判断地址类型并访问其字段。然而,这种转换需要确保地址类型与目标结构体匹配,否则可能导致数据访问错误 [^1]。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值