如何支持IPv4和IPv6连接

我目前正在做一个UDP套接字应用程序,我需要build立支持,以便IPV4和IPV6连接可以发送数据包到服务器。

我希望有人能帮助我,指出我的方向是正确的。 我发现的大部分文档都不完整。 如果你能指出Winsock和BSD套接字之间的区别,那也是有帮助的。

提前致谢!

最好的方法是创build一个也可以接受IPv4连接的IPv6服务器套接字。 为此,请创build一个常规的IPv6套接字, closures套接字选项IPV6_V6ONLY ,将其绑定到“任何”地址,并开始接收。 IPv4地址将以IPv4映射格式显示为IPv6地址。

系统之间的主要区别是IPV6_V6ONLY是否可用,以及b)默认情况下是打开还是closures。 它在Linux上默认closures(即允许没有setsockopt的双栈套接字),并在大多数其他系统上打开。

另外,Windows XP上的IPv6堆栈不支持该选项。 在这些情况下,您将需要创build两个单独的服务器套接字,并将它们放入select或多个线程中。

套接字API由IETF RFCpipe理,在所有平台(包括Windows WRT IPv6)上都应该是相同的。

对于IPv4 / IPv6应用程序, 全部是关于getaddrinfo()getnameinfo()getaddrinfo是一个天才 – 查看客户端的DNS,端口名称和function,以解决“我可以使用IPv4,IPv6还是两者都可以到达特定目的地?”这个永恒的问题。或者,如果你要去双栈路由和要它返回IPv4映射的IPv6地址,它也会这样做。

它提供了一个直接插入到bind()recvfrom()sendto()socket()的地址族中的直接sockaddr *结构。在许多情况下,这意味着没有混乱的sockaddr_in(6)结构来填写和处理。

对于UDP实现,我会小心设置双栈套接字,或更一般地说,绑定到所有接口( INADDR_ANY )。 经典的问题是,当地址没有被locking(见bind() )到特定的接口,并且系统有多个接口请求时,响应可能会根据OS路由表的意思,从多个地址的计算机的不同地址传输,混淆应用协议 – 尤其是任何有authentication要求的系统。

对于这种不是问题的UDP实现,或TCP,双栈套接字可以节省大量的时间。 必须小心,不要完全依赖双堆栈,因为不缺乏合理的平台(Old Linux,BSD,Windows 2003),而且这些平台不能configuration双堆栈套接字。

我一直在Windows下玩这个,它实际上似乎是一个安全问题,如果绑定到环回地址,那么IPv6套接字被正确绑定到[:: 1],但映射的IPv4套接字绑定到INADDR_ANY ,所以你的(据说)安全的本地应用程序实际上是暴露给世界。

RFC没有真正指定IPV6_V6ONLY套接字选项的存在,但是,如果不存在,RFC非常清楚,实现应该就像该选项是FALSE一样。

如果选项存在,我会争辩说它应该默认为FALSE,但是由于通过理解的原因,BSD和Windows实现默认为TRUE。 有一个奇怪的说法,这是一个安全问题,因为一个不知情的IPv6程序员可能会认为他们只绑定到IN6ADDR_ANY只有IPv6,并意外接受IPv4连接导致安全问题。 我认为除了令所有期待符合RFC的实现的人感到意外之外,这是既牵强又荒谬的。

在Windows的情况下,不兼容通常不会是一个惊喜。 在BSD的情况下,这是不幸的。