【问题标题】:pre-creating sockets without knowing whether they are IPv4 or IPv6在不知道它们是 IPv4 还是 IPv6 的情况下预先创建套接字
【发布时间】:2016-05-11 20:35:22
【问题描述】:

我有一些代码可以通过预先创建套接字来工作(通过。socket() BSD API),然后在以后知道地址时它会执行 connect() 等。这适用于 IPv4,但现在我也在重构以支持 IPv6。

问题在于,当我执行初始 socket() 时,我似乎需要放入 AF_INET 或 AF_INET6。但是,由于我不知道地址,但我不知道哪个是正确的。无论如何要创建一个适用于任何一个的通用套接字?如果我使用 AF_INET6 并且我在 IPv4 网络上,我是否正确地假设它不起作用?

一个相关问题 - 即使我还不知道 IP 地址,我是否可以检测到我的设备所在的网络:IPv4 还是 IPv6?假设一个网络接口,我想我只能是其中一个网络,所以如果我能找到一种方法来检测我的设备在什么类型的网络上,那么我可以在创建套接字时做到这一点。

另一种选择是仅在我知道地址时重构以创建套接字,但代码库很大,如果可能,我想避免这种情况。

我正在编写在 iOS 上运行的代码,但我不确定这是否相关。

【问题讨论】:

  • 某些平台支持 双栈 套接字(遗憾的是,iOS 不是其中之一,尤其是在 Apple 推动 iOS 仅支持 IPv6 的情况下)。如果可用,您可以为 IPv6 创建一个 AF_INET6 套接字,然后禁用其上的 IPV6_V6ONLY 选项以通过 IPv4-mapped IPv6 addresses 允许 IPv4。

标签: ios c sockets ipv6 ipv4


【解决方案1】:

你想做的事是不可能的。 socket创建的时候是和stack协议关联的,而IPV6和IPV4只是不同的stack协议。

然而,真正的问题是为什么您要预先创建套接字?为什么不在需要时创建套接字?

最后但并非最不重要的一点是,您的假设是不正确的。您的设备可以有多个接口——一个用于 IPv4,另一个用于 IPv6——并同时使用它们。

【讨论】:

  • @SanderSteffann,是的,我也很好奇。
  • 这可能是一个很好的答案(我没有投反对票),但我不确定它是否涵盖了所有内容......使用@987654323 怎么样@socket 系列,允许协议绑定等待bind... 我知道这是指监听套接字(我可以同时监听 IPv4 和 IPv6),但解释它如何应用(或不应用)可能相关t apply) 到客户端套接字。
  • @Myst,AF_UNSPEC 不是域的标准有效选项。据我所知只有 Windows 支持,OP 使用的是 OS X。
  • @SergeyA, AF_UNSPEC 在我的 Mac (BSD) 上工作,它在 Linux man page 上指定,我相信(没有检查)它符合 POSIX.1-2001。我是从Beej's guide捡来的。
  • @Myst,您所说的与问题无关。您正在谈论 getaddrinfo 参数。因为getaddrinfo 参数AF_UNSPEC 当然是有效的,并且允许您选择一个与这两个系列都匹配的接口。但这并不意味着您可以使用 AF_UNSPEC 作为域来创建套接字! (实际上是 OP 想要做的)。
猜你喜欢
  • 2016-12-10
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 1970-01-01
  • 1970-01-01
  • 2014-03-13
  • 2013-12-09
  • 2021-10-15
相关资源
最近更新 更多