代码之家  ›  专栏  ›  技术社区  ›  Charles

如何支持IPv4和IPv6连接

  •  51
  • Charles  · 技术社区  · 15 年前

    我目前正在开发一个UDP套接字应用程序,我需要内置支持,以便IPv4和IPv6连接可以向服务器发送数据包。

    我希望有人能帮助我,指出正确的方向;我发现的大多数文档都不完整。如果您能指出Winsock和BSD套接字之间的任何区别,这也会很有帮助。

    事先谢谢!

    4 回复  |  直到 9 年前
        1
  •  76
  •   duedl0r    11 年前

    最好的方法是创建一个也可以接受IPv4连接的IPv6服务器套接字。为此,请创建一个常规的IPv6套接字, 远离的 插座选项 IPV6_V6ONLY ,将其绑定到“任意”地址,然后开始接收。在 IPv4-mapped 格式。

    不同系统的主要区别在于 IPv6 6V6 a)可用,b)默认情况下打开或关闭。它在Linux上默认关闭(即允许不带setsockopt的双堆栈套接字),并且在大多数其他系统上打开。

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

        2
  •  7
  •   Craig M. Brandenburg Martin    9 年前

    套接字API由IETF RFC管理,并且在所有平台上(包括Windows WRT IPv6)都应相同。

    对于IPv4/IPv6应用程序, 所有 关于 getaddrinfo() getnameinfo() . getaddrinfo 是天才吗?看看DNS、端口名和客户端的功能,以解决“我能使用IPv4、IPv6或两者到达特定目的地吗?”_157;或者如果您要使用双堆栈路由并希望它返回IPv4映射的IPv6地址,它也会这样做。

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

    对于UDP实现,我会小心设置双栈套接字,或者更一般地说,绑定到所有接口。( INADDR_ANY )经典的问题是,当地址没有被锁定时(参见 绑定() )对于特定的接口,并且系统有多个接口请求,根据操作系统路由表的突发性,响应可能从具有多个地址的计算机的不同地址传输,从而混淆应用程序协议,尤其是任何具有身份验证要求的系统。

    对于没有问题的UDP实现或TCP,当IPV*启用系统时,双堆栈套接字可以节省大量时间。必须小心不要完全依赖于不完全必要的双栈,因为不缺少使用不支持双栈套接字的IPv6栈部署的合理平台(旧Linux、BSD、Windows 2003)。

        3
  •  4
  •   Dave    14 年前

    我一直在Windows下玩这个游戏,它实际上似乎是一个安全问题,如果您绑定到环回地址,那么ipv6套接字就正确绑定到了[::1],但是映射的ipv4套接字绑定到了inaddr_any,所以您(假设)安全的本地应用程序实际上是向世界公开的。

        4
  •  3
  •   Owen DeLong    14 年前

    RFC并没有真正指定是否存在ipv6 v6only socket选项,但是,如果不存在,则RFC很明显,实现应该像该选项为false一样。

    如果存在该选项,我会争辩说它应该默认为false,但是由于传递理解的原因,BSD和Windows实现默认为true。有一种奇怪的说法认为这是一个安全问题,因为一个不知情的ipv6程序员可能会认为他们只绑定到in6addr_any(仅针对ipv6),并意外地接受一个ipv4连接,从而导致安全问题。我认为这既牵强又荒谬,除了让任何期待符合RFC实现的人感到惊讶之外。

    在Windows中,不遵守通常不会令人惊讶。对于BSD来说,这充其量是不幸的。