【问题标题】:how to determine socket interface type如何确定套接字接口类型
【发布时间】:2019-08-30 19:15:18
【问题描述】:

问题的一点背景:

我最近对 ​​Microsoft 和套接字绑定有过一次濒死体验。我正在测试生产代码,其中一台测试 PC 一直失败。我最终建议bind() 函数中存在错误,这是最古老的函数之一。

我提交了错误(请参阅 Visual Studio 的开发人员社区反馈论坛中的 CAsyncSocket Create's bind implementation has a bug),但被移交给了 Windows 团队(请参阅他们的反馈中心中的“__imp_bind 实现有一个长期存在的情境错误”),谁从来没有做过任何事情。

由于我无法调试 bind(),并且 Microsoft 拒绝提供帮助,经过 2 周的开发工作后,我最终发现,有问题的测试机器启用了 Hyper-V,而我的接口解析代码正在拾取这个虚假的AF_INET 地址并解析它而不是真实的 IP 地址。

我不能指望我的客户仅仅为了运行我的软件而关闭不需要的 Hyper-V 功能,因此我需要使我的解析代码更加精细。

我的问题:

我需要做的是能够获取特定地址的详细名称,例如ipconfig /all。我可以看到其他人也问过这个问题,比如 Ivan 的 how to determine interface name 和 tez 的 Linux getting all network interface names。 Ivan 的答案是使用getsockname(),tez 的答案是使用if_nameindex()。两者都没有返回详细的接口名称,如 ipconfig 所示。

那么,有人知道那会是什么函数调用吗?

【问题讨论】:

  • 在 Windows 上,查看GetAdaptersInfo()(XP 及更早版本)和GetAdaptersAddresses()(Vista 及更高版本)、GetInterfaceInfo() 等。您只能从getsockname() 获取套接字的真实本地 IP在它被bind()ed 到特定IP 之后,或者在accept()ed 或connect()ed 如果绑定到通配符IP 之后,然后您可以在地址表中查找IP 以找到其接口索引,然后在接口表中查找该索引以获取其可读名称。
  • 话虽如此,Hyper-V 究竟是什么原因破坏了您的代码?你能详细说明一下吗?世界上 99% 的套接字代码并没有对 Hyper-V 做任何特别的事情,而且它“正常工作”,那么 Hyper-V 在您的特定环境中到底是什么破坏了?你能提供一个不适合你的minimal reproducible example 吗?您的代码如何设置套接字?期望的结果是什么?实际结果如何?
  • GetAdaptersAddresses() 会正常工作。我的接口解析代码不是很复杂,只是抓取了第一个解析的 AF_INET 接口。当然,现在 Ipv6 出现了,还有更多无法解释的接口出现,例如 Npcap Loopback AdapterHyper-V... 然后 family 不足以解决问题。问题不是 bind() 中的错误,而是在解决时无法更好地区分。一旦我使用 GetAdaptersAddresses() 做到这一点,幻像 bind() 问题就会消失。
  • 那么,您正试图通过接口名称bind() 一个套接字?为什么不直接通过IPbind()它,然后要求用户提供正确的IP才能使用?一个网络接口可以分配有多个 IP,因此仅一个名称可能是不够的,除非您 bind() 为该接口实际拥有的每个 IP 提供一个单独的套接字。
  • 问题出现在我的华硕测试机上,但没有出现在戴尔测试机上。这两台机器都打开了 Hyper-V。经过大量调试后,我才意识到正在为华硕解决错误的接口。如果我没记错的话,在华硕上,链表接口顺序与戴尔上的不同,这使我的顺序解析接口代码出错,其中 Hyper-V 接口首先出现在华硕上。为什么两个硬件平台的链表接口顺序不同,我不知道。但很明显,我的代码不应该对这种变化敏感。

标签: sockets mfc bind casyncsocket


【解决方案1】:

Remy Lebeau 的答案是使用GetAdaptersAddresses。该函数的示例代码显示了如何遍历套接字适配器接口并获取大量接口数据。然而,要回答这个问题(即,得到ipconfig 般的冗长),您需要单独的IP 地址。这些在LPSOCKADDR lpSockaddr 成员中可用,它们是GetAdaptersAddresses 调用的输出,例如pUnicast->Address.lpSockaddr

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 2020-06-25
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多