struct sockaddr_in
结构体用于表示 IPv4 地址和端口号,如果要绑定 IPv6 地址和端口号,需要使用 struct sockaddr_in6
结构体。下面分别介绍 struct sockaddr_in6
结构体各个字段的含义。
struct sockaddr_in6 {
sa_family_t sin6_family; // 地址族(Address Family),通常为AF_INET6
in_port_t sin6_port; // 端口号,使用网络字节序(Network Byte Order)
uint32_t sin6_flowinfo; // 流信息(Flow Information)
struct in6_addr sin6_addr; // IPv6地址结构体
uint32_t sin6_scope_id; // 范围ID(Scope ID)
};
sin6_family
: 表示地址族(Address Family),即协议族。对于IPv6而言,通常为AF_INET6。sin6_port
: 表示端口号,使用网络字节序(Network Byte Order)。与IPv4相同,范围为0~65535。sin6_flowinfo
: 用于指定IPV6流量标签信息。sin6_addr
: 表示IPv6地址结构体,包含一个16字节长的数组成员s_addr代表IP地址。由于该变量存储顺序与主机字节序有关,在进行网络传输时需要将其转换为网络字节序。可以使用inet_pton()函数将字符串形式的IP地址转换成in_addr_t类型的二进制数据;或者使用inet_pton()函数将字符串形式的IP地址直接转换成128位无符号整数型数据。sin6_scope_id
: 用于指定IPv6地址的范围ID,仅在链路本地和站点本地地址中有意义。
当需要绑定IPv6时,可以使用bind()
函数,并且参数中的sockaddr
结构体类型应为struct sockaddr_in6
。例如:
int sockfd = socket(AF_INET6, SOCK_STREAM, 0); // 创建IPv6套接字
struct sockaddr_in6 addr; // IPv6地址结构体
memset(&addr, 0, sizeof(addr)); // 清空结构体
// 填充IPv6地址信息
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(8080);
inet_pton(AF_INET6, "::1", &addr.sin_addr);
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
在上述代码中,首先创建了一个IPv6套接字,并初始化了一个 struct sockaddr_in6
结构体来表示要绑定的 IPv6 地址和端口号。其中使用 inet_pton()
函数将字符串形式的 IPv6 地址转换为网络字节序的二进制数据,最后通过 bind()
函数将套接字与该地址进行绑定。