c - inet_ntop 返回部分不正确的 IPv6 地址
问题描述
我知道这个类似的问题,但答案没有意义,可能是针对不同的问题。
在我的 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
解决方案
的手册页getpeername(2)
提示了为什么会发生这种情况:
address_len 参数应该被初始化以指示地址指向的空间量。返回时,它包含返回地址的实际大小(以字节为单位)。
如果提供的缓冲区太小,地址将被截断。
的大小struct sockaddr
对于 IPv6 地址来说太小,会导致地址被截断。
您需要使用struct sockaddr_storage
withgetpeername
而不仅仅是struct sockaddr
struct sockaddr_storage addr;
socklen_t addr_len = sizeof(addr);
getpeername(socket, (struct sockaddr *)&addr, &addr_len)
推荐阅读
- javascript - 为什么我需要在 Express 中将 (req, res, next) 传递给 bodyParser?
- python - Pandas:read_csv 错误地生成了第一个元素为特殊字符的 NaN 数据帧
- php - FFMpeg PHP 包在 Laravel 队列中加载时出错
- android - 如何修复 java.io.FileNotFoundException?
- javascript - 如何在 Visual Studio 代码中与文件一起导入扩展名?
- android - 如何更改 Android Date Picker 的字体系列?
- php - 如何在动态表中的特定行更改输入类型 =“文件”名称
- vba - VBA 使用 FileDialog 作为循环中的文件夹路径
- python - Python tkinter 崩溃经常更新 ProgressBar 元素
- adfs - 关于在 Windows Server 2019 上自定义 ADFS