如何支持IPv4和IPv6连接

Cha*_*les 52 c++ sockets winsock ipv4 ipv6

我目前正在研究UDP套接字应用程序,我需要内置支持,以便IPV4和IPV6连接可以将数据包发送到服务器.

我希望有人可以帮助我,并指出我正确的方向; 我发现的大部分文档都不完整.如果你能指出Winsock和BSD套接字之间的任何差异,也会有所帮助.

提前致谢!

Mar*_*wis 80

最好的方法是创建一个也可以接受IPv4连接的IPv6服务器套接字.为此,请创建常规IPv6套接字,关闭套接字选项IPV6_V6ONLY,将其绑定到"任何"地址,然后开始接收.IPv4地址将以IPv4映射格式显示为IPv6地址.

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

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

  • 在Linux上默认关闭IPV6_V6ONLY是错误的:它取决于操作系统,而不仅仅取决于内核.例如,在Debian GNU/Linux上,它最近默认切换为on. (7认同)
  • Windows上的默认设置已启用(仅在Win7上实现). (2认同)
  • 如果IPV6_V6ONLY不可用,是否意味着操作系统不支持双堆叠? (2认同)
  • 您能否指出支持 IPv4 和 IPv6 连接(也解析 IPv4 映射格式)的示例源代码? (2认同)

Ein*_*ein 7

套接字API由IETF RFC管理,在所有平台上都应该相同,包括Windows WRT IPv6.

对于IPv4/IPv6应用程序,它是关于和的全部. 是一个天才 - 查看客户端的DNS,端口名称和功能,以解决"我可以使用IPv4,IPv6或两者到达特定目的地吗?"的永恒问题.或者,如果您要使用双栈路由并且想要要返回IPv4映射的IPv6地址,它也会这样做.getaddrinfo()getnameinfo()getaddrinfo

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

对于UDP实现,我会小心设置双栈套接字,或者更一般地说,绑定到所有接口(INADDR_ANY).经典的问题是,当地址没有被锁定(参见bind())特定接口并且系统有多个接口请求时,响应可能会从具有多个地址的计算机的不同地址传输,这些地址基于OS路由表的异想天开,混淆了应用程序协议 - 特别是任何具有身份验证要求的系统.

对于没有问题的UDP实现或TCP,双堆栈套接字可以在使用IPv*启用系统时节省大量时间.必须小心不要完全依赖双栈,因为它并不是绝对必要的,因为没有合理的平台(旧Linux,BSD,Windows 2003)部署IPv6堆栈不能兼容双栈.