将IPV4套接字(sockaddr_in)与IPV6套接字(sockaddr_in6)进行比较
Comparing IPV4 socket(sockaddr_in) with IPV6 Socket(sockaddr_in6)
我有一个UDP服务器,它必须为IPV4和IPV6地址上的客户端提供服务。我创建了一个单独的IPV6套接字来为IPV4和IPV6客户端提供服务
服务器在第一次通信时存储客户端的IPAddress。如果是IPV4客户端,则存储为IPV4地址;如果是IPV6客户端,则服务器存储为IPV6地址。对于所有未来的通信,它检查存储器是否已经知道(存储)该客户端,然后相应地采取行动。为了将客户端地址与存储的地址进行比较,我根据家族类型(AF_INET和AF_INET6)执行memcmp
在与IPV6客户端通信时,系统工作正常,但在与IPV4客户端通信时系统的行为就好像它从不了解客户端一样。在调试过程中,我发现由于IPV6的套接字类型,IPV4客户端的IPAddresss被接收为IPV6映射的IPV4 Address,其系列设置为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/C++Unix
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 如何通过套接字将文本文件的内容从服务器发送到客户端
- 如何在C/C++中用FD_set Unix设置套接字文件描述符
- 套接字读取后,我在缓冲区中看到意外输入
- 如何在CPP中创建应该在Windows和Linux上运行的套接字?
- 我可以与 python 服务器而不是 c++ 客户端建立 tcp/ip 套接字吗?
- 套接字连接"Operation not permitted"错误,甚至使用升压/平发器根.cpp
- WINAPI 注册应用程序重新启动时不清除打开的套接字
- (Winsock) UDP 接收工作正常,但同一套接字的发送失败
- MSG_WAITALL的套接字发送得到了 22 EINVAL
- C++套接字客户端到 Python 服务器未创建连接
- 在不知道套接字的情况下关闭网络连接
- C++套接字对不读/写父/子
- 非更新套接字消息
- SIGSEGV on Boost UDP 套接字关闭 - tcache_get at malloc.c.
- 将"uint8_t"(从套接字读取)隐式转换为"char"安全吗
- 当对套接字 send() 的同步调用由于连接另一端丢失而被阻止时,如何恢复?
- 当客户端在 write() 期间终止连接时,由对等套接字错误重置连接
- 套接字编程:结构 sockaddr VS 结构sockaddr_in