我知道sockaddr_in用于IPv4,sockaddr_in 6用于IPv6.我感到困惑的是[6]中sockaddr和sockaddr_之间的区别.
有些函数接受sockaddr
,有些函数接受sockaddr_in
或sockaddr_in6
,因此:
- 规则是什么?
- 为什么需要两种不同的 struct ?
而且因为这sizeof(sockaddr_in6) > sizeof(sockaddr) == sizeof(sockaddr_in)
美元.
- 这是否意味着如果我们需要支持IPv4和IPv6,我们应该始终使用sockaddr_in6来分配堆栈中的内存,并强制转换为sockaddr和sockaddr_in?
一个例子是:我们有一个套接字,我们想得到它的字符串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));
}