gpt4 book ai didi

c++ - 比较 IPV4 套接字 (sockaddr_in) 和 IPV6 套接字 (sockaddr_in6)

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:45:17 24 4
gpt4 key购买 nike

我有一个 UDP 服务器,它必须同时为 IPV4 和 IPV6 地址上的客户端提供服务。我创建了一个 IPV6 套接字来同时为 IPV4 和 IPV6 客户端提供服务。

服务器在第一次通信时存储客户端的IP地址。如果它是 IPV4 客户端,它存储为 IPV4 地址,如果它是 IPV6 客户端,则服务器存储为 IPV6 地址。对于所有 future 的通信,它会检查存储是否已经知道(存储)此客户端,然后采取相应的行动。为了将客户端地址与存储的地址进行比较,我根据家族类型(AF_INET 和 AF_INET6)执行了 memcmp。

在与 IPV6 客户端通信时,系统工作正常,但在与 IPV4 客户端通信时,系统表现得好像它从不认识客户。在调试时,我发现由于 IPV6,IPV4 客户端的套接字类型 IPAddresss 被接收为 IPV6 映射的 IPV4 地址,并且系列设置为 IPV6。为了解决这个问题,我需要比较 IPV4 存储地址和 IPV6 映射地址。为此,我使用 IPV4 结构的 sin_addr.s_addr 和 IPV6 结构的 sin6_addr.in6_u.u6_addr32。请在下面找到代码片段。

ipv6_clientdata = (const struct sockaddr_in6 *)&sockStor;
ipv4_storeddata = (const struct sockaddr_in *)&(_stData[index].clientaddr);
if( (ipv6_clientdata->sin6_port == ipv4_storeddata->sin_port) &&
(ipv6_clientdata->sin6_addr.in6_u.u6_addr32[3] == ipv4_storeddata->sin_addr.s_addr)
)
{
addrfound = true;
}

我想知道这种方法是否是将 IPV6 映射的 IPV4 地址与 IPV4 地址进行比较的正确解决方案,或者是否有其他更好的方法。

最佳答案

作为Joachim Pileborg因此,当 IPv4 地址来自同一套接字上接收到的较早数据包时,您无需关心这一点,因为您会将一个映射的 IPv4 地址与另一个进行比较。仅当 IPv4 地址是从您必须关心的外部来源获得的情况下。

作为João Augusto指出,在比较最后 32 位之前,您忽略了检查 IPv6 地址是否确实是 IPv4 映射地址。有一个宏 IN6_IS_ADDR_V4MAPPED 可以帮助您执行此操作:

if (
IN6_IS_ADDR_V4MAPPED(&(ipv6_clientdata->sin6_addr)) &&
(ipv6_clientdata->sin6_port == ipv4_storeddata->sin_port) &&
(ipv6_clientdata->sin6_addr.in6_u.u6_addr32[3] == ipv4_storeddata->sin_addr.s_addr)
) {
addrfound = true;
}

关于c++ - 比较 IPV4 套接字 (sockaddr_in) 和 IPV6 套接字 (sockaddr_in6),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11718176/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com