我知道 sockaddr_in 用于 IPv4,而 sockaddr_in6 用于 IPv6。让我感到困惑的是 sockaddr 和 sockaddr_in[6] 之间的区别。
有些函数接受sockaddr
,有些函数接受sockaddr_in
或sockaddr_in6
,所以:
- 什么是规则?
- 为什么需要两种不同的结构?
因为 sizeof(sockaddr_in6) > sizeof(sockaddr) == sizeof(sockaddr_in)
。
- 这是否意味着如果我们需要支持 ipv4 和 ipv6,我们应该始终使用 sockaddr_in6 在堆栈中分配内存并强制转换为 sockaddr 和 sockaddr_in?
一个例子是:我们有一个socket,我们想得到它的字符串ip地址(可以是ipv4或者ipv6)。
我们先调用getsockname
得到一个addr
,然后根据addr.sa_family
调用inet_ntop
。
这段代码有什么问题吗?
char ipStr[256];
sockaddr_in6 addr_inv6;
sockaddr* addr = (sockaddr*)&addr_inv6;
sockaddr_in* addr_in = (sockaddr_in*)&addr_inv6;
socklen_t len = sizeof(addr_inv6);
getsockname(_socket, addr, &len);
if (addr->sa_family == AF_INET6) {
inet_ntop(addr_inv6.sin6_family, &addr_inv6.sin6_addr, ipStr, sizeof(ipStr));
// <<<<<<<<IS THIS LINE VALID, getsockname expected a sockaddr, but we use
// it output parameter as sockaddr_in6.
} else {
inet_ntop(addr_in->sin_family, &addr_in->sin_addr, ipStr, sizeof(ipStr));
}
最佳答案
sockaddr_in
和 sockaddr_in6
都是第一个成员是 sockaddr
的结构结构。
根据C标准,结构的地址和它的第一个成员是相同的,所以你可以将指针转换为sockaddr_in(6)
在指向 sockaddr
的指针中.
函数采用sockaddr_in(6)
作为参数可以修改sockaddr
部分和函数采用 sockaddr
作为参数只关心那部分。
有点像继承。
关于c++ - sockaddr、sockaddr_in 和 sockaddr_in6 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18609397/