in_addr与sockaddr

本文详细介绍了网络编程中常用的IP地址结构in_addr及端口地址结构sockaddr_in。阐述了in_addr_t如何表示32位IP地址,并通过实例说明了如何将IP地址转换为字符串形式。此外还解释了sockaddr_in结构体各字段的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

struct in_addr{
in_addr_t s_addr;
};
结构体in_addr表示一个32位IP地址的结构体
in_addr_t 一般为 32位的unsigned int,其字节顺序为网络顺序(network byte ordered),即该无符号整数采用大端字节序 [1] 。.
其中每8位代表一个IP地址位中的一个数值
例如192.e168.3.144记为0xc0a80390,其中 c0 为192 ,a8 为 168, 03 为 3 , 90 为 144
打印的时候可以调用 inet_ntoa()函数将其转换为char *类型.
打印的时候用printf("the ip addr is %s\n",inet_ntoa(sockaddr_in.in_addr));来打印点分IP地址
表示一个主机的端口地址(包括IP地址和端口号)的结构体是struct sockaddr 这个结构体可以由struct sockaddr_in等其他地址结构体强制转换而来。
struct sockaddr_in
{
    sa_family_t sin_family;
    in_port_t sin_port;
    struct in_addr;
    unsigned char  sin_zero[8];
} 
socket结构体中含有这个struct sockaddr地址。
<think>我们被要求解释给定的结构体 `struct sockaddr_in`,并回答相关问题。根据示例,我们需要在回答后提出3-5个相关问题,并以“§§相关问题§§”开头。 结构体 `sockaddr_in` 用于IPv4地址的套接字地址表示。下面我们将详细解释这个结构体的各个成员。</think>### `struct sockaddr_in` 结构详解 #### 结构体定义解析 ```c struct sockaddr_in { __SOCKADDR_COMMON (sin_); // 地址族标识(如AF_INET) in_port_t sin_port; // 16位端口号(网络字节序) struct in_addr sin_addr; // 32位IP地址(网络字节序) unsigned char sin_zero[8]; // 填充字节(全置0) }; ``` #### 核心成员说明 1. **`__SOCKADDR_COMMON (sin_)`** - 宏定义展开为 `sa_family_t sin_family;` - 指定地址族:IPv4固定为 `AF_INET`(值=2) 2. **`sin_port`** - 类型:`in_port_t`(实际为`uint16_t`) - 存储格式:**网络字节序**(大端序) - 示例:端口80需转换为 `htons(80)` 3. **`sin_addr`** ```c struct in_addr { in_addr_t s_addr; // uint32_t(4字节IP地址) }; ``` - IP转换函数: - 字符串→二进制:`inet_pton(AF_INET, "192.168.1.1", &addr.sin_addr)` - 二进制→字符串:`inet_ntoa(addr.sin_addr)` 4. **`sin_zero[8]`** - 作用:填充使结构体大小等于 `struct sockaddr` - 必须初始化为0:`memset(&addr.sin_zero, 0, sizeof(addr.sin_zero));` #### 内存布局示意图 ``` 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Address Family (2 bytes) | Port Number (2 bytes) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | IP Address (4 bytes) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Padding (8 bytes) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` #### 使用示例(TCP服务器绑定) ```c #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main() { int sockfd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(8080); // 端口8080 inet_pton(AF_INET, "0.0.0.0", &server_addr.sin_addr); // 监听所有接口 memset(server_addr.sin_zero, 0, sizeof(server_addr.sin_zero)); bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)); listen(sockfd, 5); // ... 后续处理 return 0; } ``` #### `sockaddr`的关系 ```c struct sockaddr { sa_family_t sa_family; // 地址族 char sa_data[14]; // 地址数据 }; ``` - **类型转换**:因C语言缺乏继承,需强制转换: ```c struct sockaddr_in addr_in; struct sockaddr *addr = (struct sockaddr*)&addr_in; ``` #### 关键注意事项 1. **字节序问题**: - 主机序→网络序:`htons()`(端口)、`htonl()`(IP) - 网络序→主机序:`ntohs()`、`ntohl()` 2. **IPv6兼容**: - IPv6需使用 `sockaddr_in6` - 通用编程模式: ```c struct sockaddr_storage addr; // 足够存储IPv4/IPv6 ``` 3. **安全初始化**: ```c struct sockaddr_in addr = {0}; // 零初始化防止内存泄漏 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值