inet_ntop返回部分不正确的IPv6地址

问题描述 投票:0回答:1

我知道这个similar question,但是答案没有意义,可能是针对其他问题。

在我的iOS应用中,我使用CFSockets连接到服务器,并希望显示服务器的远程地址。使用IPv4时,它可以按预期工作,但是IPv6的结果很奇怪,其中地址的网络前缀正确,但是主机位完全不同。

int sock_fd = <...> // Assume I already have the fd
struct sockaddr addr;
socklen_t addr_len = sizeof(addr);
getpeername(sock_fd, &addr, &addr_len);
char addressString[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr, addressString, INET6_ADDRSTRLEN);

我期望的是2607:f2f8:a4c8::2,但得到的是一个地址,该地址具有正确的网络前缀,但每次都有不同的主机位,例如:

               vvvvvvvvvvvvvvvvvvvv Random?
2607:f2f8:a4c8:0:c400:13b0:f6c5:afa
^^^^^^^^^^^^^^ Correct

c posix
1个回答
0
投票

getpeername(2)的手册页提供了有关发生这种情况的提示:

address_len参数应初始化以指示地址指向的空间量。返回时,它包含返回地址的实际大小(以字节为单位)。

如果提供的缓冲区太小,地址将被截断。

struct sockaddr的大小对于IPv6地址而言太小,将导致该地址被截断。

您需要将struct sockaddr_storagegetpeername一起使用,而不仅仅是struct sockaddr

struct sockaddr_storage addr;
socklen_t addr_len = sizeof(addr);
getpeername(socket, (struct sockaddr *)&addr, &addr_len)
© www.soinside.com 2019 - 2024. All rights reserved.