我有一个UDP服务器,它必须同时为IPV4和IPV6地址上的客户端提供服务。我创建了一个IPV6套接字来同时为IPV4和IPV6客户端服务。
服务器在第一次通信时存储客户端的IPAddress。如果是IPV4客户端,则存储为IPV4地址;如果是IPV6客户端,则服务器存储为IPV6地址。对于以后的所有通信,它检查存储是否已知(存储)该客户端,然后相应地执行操作。为了将客户端地址与存储的地址进行比较,我根据族类型(AF_INET和AF_INET6)执行一个memcmp。
与IPV6客户端通信时,系统工作正常,但与IPV4客户端通信时,系统的行为就好像它从来不认识该客户端一样。在调试过程中,我发现由于IPV6的套接字类型,IPV4客户端的IPAddresss被接收为IPV6映射的IPV4地址,其族设置为IPV6。为了解决这个问题,我需要比较IPV4存储地址和IPV6映射地址。为此,我使用IPV4结构的sin_addr.s_addr和IPV6结构的sin_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;
}
正如Joachim Pileborg所推断的,当IPv4地址来自同一套接字上较早收到的数据包时,您不需要关心这一点,因为您将比较一个映射的IPv4地址和另一个映射的IPv4地址。只有在IPv4地址是从外部来源获得的情况下,您才需要关心。
正如João Augusto所指出的,在比较最后32位之前,您忽略了检查IPv6地址是否确实是IPv4映射地址。在6_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;
}
问题内容: 我试图理解SocketChannels和NIO。我知道如何使用常规套接字,以及如何制作一个简单的每客户端线程服务器(使用常规阻塞套接字)。 所以我的问题是: 什么是SocketChannel? 当使用SocketChannel而不是Socket时,我还能得到什么呢? 通道和缓冲区之间是什么关系? 什么是选择器? 文档中的第一句话是。那是什么意思? 我也阅读了本文档,但是不知何故…… 问
我有一个python应用程序,它需要为IPv6连接选择一个特定的本地源地址,但可以为IPv4连接使用“any”0.0.0.0。但应用程序在中使用主机名,以允许从名称查找地址。 那么,如果在调用之前我不知道是IPv4地址还是IPv6地址,那么如何将特定的IPv6源地址和IPv4“any”地址绑定到本地套接字? 一定有更好的办法。我怀疑我必须自己实现地址查找和选择,并将地址而不是名称传递给。这样,在进
你好,我想问一下使用这个有什么不同: 谢谢你的回答
socket_read和socket_recv之间有什么区别?我正在尝试使用PHP套接字,但使用socket_read时收到了以下警告: 请帮帮我!
试着找出我做错了什么。我一直收到这样的错误:“失败:WebSocket握手期间出错:Sec WebSocket接受不匹配”。 下面是我从服务器得到的: 我采用了“EN04JZBFLCFCHK5QNUXJG==”并添加了“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”以获得以下内容: 所以我的回应是: 我不确定我做错了什么,但从我在其他示例中看到的情况来看,我的webso
此函数创建sockaddr_in6: 基本上,如果地址是IPv4地址,我会在它前面加上,并将该族设置为af_inet。 这有可能做到。如果是,我做错了什么?